boots, presents shell prompt, and doesn't crash immediately
This commit is contained in:
parent
e082e0b31d
commit
8461eac15e
|
@ -1,12 +1,13 @@
|
|||
<$Revision: 1.7 $>
|
||||
<$Revision: 1.8 $>
|
||||
|
||||
This is to be a summary of the status of code, its problems,
|
||||
and the directions it should and take in the future.
|
||||
and the direction it should take in the future.
|
||||
|
||||
Summary: Execs SunOS /sbin/init. executes system calls but when it forks, the
|
||||
new process segfaults immediately. Possibly some bug in
|
||||
softclock() processing, as scheduling may be muffed.
|
||||
All this via nfs_diskless since there is no scsi driver.
|
||||
Summary: Boots via nfsdiskless (due to lack of a scsi driver),
|
||||
execs /sbin/init (MID_M68K), and because single-user is forced,
|
||||
provides a /bin/sh. It works, though the console driver is flakey
|
||||
and there are a bunch of vm/pmap assertions that should be
|
||||
investigated
|
||||
|
||||
nfs_diskless structure is hardwired :)
|
||||
|
||||
|
|
|
@ -1,4 +1,116 @@
|
|||
THINGS TO BE DONE: (NetBSD/Sun3 version) <$Revision: 1.2 $>
|
||||
THINGS TO BE DONE: (NetBSD/Sun3 version) <$Revision: 1.3 $>
|
||||
|
||||
This is a list of things that need to be done for NetBSD/Sun3. Some
|
||||
of these tasks are small, others are large. Some are extremely
|
||||
critical, others would be useful to do, and some are fluff. Included
|
||||
in each description, is a notation of its importance. Please note
|
||||
however that this is a list of things to do above and beyond fixing
|
||||
bugs in the existing code base.
|
||||
|
||||
In general there are some guidelines for work to be included in
|
||||
NetBSD. Chief among these are:
|
||||
|
||||
(1) Keep GPLed stuff out of the kernel.
|
||||
(2) Only clean code, that lends itself to further enhancement
|
||||
(3) Keep architecture dependent code out of architecture independent
|
||||
directories
|
||||
|
||||
The important part of this is that the sun3 stuff better stay in
|
||||
sys/arch/sun3.
|
||||
|
||||
Bootstrapping:
|
||||
|
||||
make it easy to do nfs diskless (CRITICAL). currently you have to
|
||||
hack up the nfs_diskless sturcture. this should be fixed by finishing
|
||||
porting sys/lib/libnetboot.
|
||||
|
||||
native boot blocks (HIGH)
|
||||
|
||||
nfs diskless boot blocks (HIGH).
|
||||
|
||||
Kernel core tasks (arch/sun3/sun3):
|
||||
|
||||
make pmap module modifications necessary so that we can turn
|
||||
on MACHINE_NONCONTIG,a kernel config option that allows for
|
||||
non-contiguous physical memory. This work is necessitated by the
|
||||
the frame buffer on the 3/50 which is plop in the middle of physical
|
||||
ram. (CRITICAL)
|
||||
|
||||
kernel text is not protected. (CRITICAL..for debugging)
|
||||
|
||||
find out why kernel has to be linked with such wierd options. (HIGH)
|
||||
|
||||
test virtual addressed cache support on non-desktop machines. (HIGH)
|
||||
|
||||
need support for the sun eeprom, including a non-sun
|
||||
copyrighted header file describing its structure. Needed
|
||||
at least for console handling. (MEDIUM)
|
||||
|
||||
ddb support (MEDIUM) (mycroft is working on this, for 68ks in general,
|
||||
and it may actually work some now)
|
||||
|
||||
locore.s got split into many pieces as part of a bit of research
|
||||
by the author into how much of it was truly sun-dependent vs
|
||||
68k-dependent. Needs to be re-integrated into a standard
|
||||
locore.s so that we can benefit from changes to the hp300, and
|
||||
amiga ports, and vice-versa. (MEDIUM, will be fixed by glass)
|
||||
|
||||
FPUCOPROC support needs to be better integrated and triggered
|
||||
by something other than this awful define. Also need
|
||||
FPU emulation code (see briggs). (MEDIUM)
|
||||
|
||||
msgbuf should be allocated later, using the pmap stuff, same with
|
||||
high_segment crud. see the dvma_alloc code for an example of
|
||||
how much cleaner this is. (LOW..it works now)
|
||||
|
||||
compute idprom checksum, and check it (was lazy) (LOW)
|
||||
|
||||
HPUX compatibility support (make it hang off p_emul like our
|
||||
COMPAT_SUNOS support). (LOW)
|
||||
|
||||
pmap module should keep a 3-level cache of ptes instead of 2. (LOW)
|
||||
|
||||
need /dev/eeprom driver functionality added to mem.c (LOW)
|
||||
|
||||
support for sun3x architecture (LOW, but we have the 030 code)
|
||||
|
||||
Device-driver related tasks:
|
||||
|
||||
scsi driver - use the scsi infrastructure in sys/scsi.
|
||||
See config-file component in sys/arch/i386/conf
|
||||
For host-adapter driver examples look
|
||||
in sys/arch/{386/isa,mac68k/dev}
|
||||
host adapter chip is NCR 5380.
|
||||
dma chip is amd 9516.
|
||||
secondary sources in: mac port, sprite, mach3
|
||||
(SUPER_DUPER_CRITICAL)
|
||||
|
||||
prom console can accept input, though it does so lamely
|
||||
|
||||
make zs, ms, kbd driver as incorporated from torek's code actually
|
||||
work. Then re-engineer such that it isn't so ugly. (CRITICAL)
|
||||
|
||||
intel ether - driver for 'ie' intel 82586-based ethernet.
|
||||
see mach3, sprite, and i386 port (CRITICAL)
|
||||
|
||||
VME support (CRITICAL)
|
||||
|
||||
console handling (choice, detection, etc.) (MEDIUM)
|
||||
|
||||
OBIO probe support needed. support for handling the traps is
|
||||
already present in the form of pcb_onfault. (MEDIUM)
|
||||
|
||||
Better OBIO configuration architecture, less re-computation of
|
||||
default parameters. device-conflict notification. Requires
|
||||
mycroft's autoconfig fix. (MEDIUM)
|
||||
|
||||
bw?, cg*,fb - must have same external interface as sun's to
|
||||
keep X happy.
|
||||
see sparc, and sprite code. (MEDIUM)
|
||||
|
||||
lance - switch to sparc code as a base instead of hp300. (LOW)
|
||||
|
||||
THINGS TO BE DONE: (NetBSD/Sun3 version) <$Revision: 1.3 $>
|
||||
|
||||
This is a list of things that need to be done for NetBSD/Sun3. Some
|
||||
of these tasks are small, others are large. Some are extremely
|
||||
|
|
|
@ -1,31 +1,45 @@
|
|||
#
|
||||
# new config file for GENERIC
|
||||
#
|
||||
machine "sun3"
|
||||
cpu "SUN3_160"
|
||||
cpu "SUN3_50"
|
||||
cpu "SUN3_260"
|
||||
cpu "SUN3_110"
|
||||
cpu "SUN3_60"
|
||||
cpu "SUN3_E"
|
||||
cpu "SUN3_60"
|
||||
|
||||
ident SOLIPSIST
|
||||
include "std.sun3"
|
||||
|
||||
timezone 8 dst
|
||||
maxusers 16
|
||||
options "SUN3_50"
|
||||
options "SUN3_60"
|
||||
|
||||
makeoptions DEBUG = "-g"
|
||||
maxusers 4
|
||||
options TIMEZONE = 480, DST = 2, MAXFDESCS=2048
|
||||
|
||||
# Standard options
|
||||
options "COMPAT_43"
|
||||
options "TCP_COMPAT_42"
|
||||
options FOO=3
|
||||
|
||||
# Options for all SUN3 machines
|
||||
options SWAPPAGER, VNODEPAGER, DEVPAGER
|
||||
options KTRACE
|
||||
options INET
|
||||
options FFS
|
||||
options NFSSERVER
|
||||
options NFSCLIENT
|
||||
|
||||
#sun3-specific options
|
||||
options COMPAT_SUNOS
|
||||
|
||||
# sun3 debug options
|
||||
#options CONTEXT_DEBUG
|
||||
#options VMFAULT_TRACE
|
||||
#options EXEC_DEBUG
|
||||
#options LAME_ZS
|
||||
|
||||
config netbsd swap generic
|
||||
|
||||
le0 at obio? addr ? level 3
|
||||
#zs0 at obio? addr 0x00000 level 3
|
||||
#zs1 at obio? addr 0x20000 level 3
|
||||
|
||||
pseudo-device swappager
|
||||
pseudo-device vnodepager
|
||||
pseudo-device devpager
|
||||
idprom0 at obctl? addr ? size ?
|
||||
|
||||
prom0 at mainbus0
|
||||
|
||||
pseudo-device loop
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile.sun3,v 1.13 1994/02/04 08:19:41 glass Exp $
|
||||
# $Id: Makefile.sun3,v 1.14 1994/02/23 08:28:21 glass Exp $
|
||||
# Makefile for 4.4 BSD
|
||||
#
|
||||
# This makefile is constructed from a machine description:
|
||||
|
@ -33,7 +33,7 @@ S= ../../../..
|
|||
SUN3= ../..
|
||||
LIBKERN=../libkern.a
|
||||
|
||||
INCLUDES= -I. -I$S -I$S/sys
|
||||
INCLUDES= -I. -I../.. -I$S -I$S/sys
|
||||
COPTS= ${INCLUDES} ${IDENT} -DKERNEL -Dmc68020 -Dsun3
|
||||
CFLAGS= ${COPTS}
|
||||
|
||||
|
|
|
@ -27,9 +27,10 @@ options NFSCLIENT
|
|||
options COMPAT_SUNOS
|
||||
|
||||
# sun3 debug options
|
||||
options CONTEXT_DEBUG
|
||||
options VMFAULT_TRACE
|
||||
options EXEC_DEBUG
|
||||
#options CONTEXT_DEBUG
|
||||
#options VMFAULT_TRACE
|
||||
#options EXEC_DEBUG
|
||||
#options LAME_ZS
|
||||
|
||||
include "TIMESINK.nfsdiskless" #mega sad
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: files.sun3.newconf,v 1.8 1994/02/04 08:19:43 glass Exp $
|
||||
# $Id: files.sun3.newconf,v 1.9 1994/02/23 08:28:24 glass Exp $
|
||||
# sun3-specific configuration info
|
||||
|
||||
maxusers 2 8 64
|
||||
|
@ -18,12 +18,38 @@ device le at obio: ifnet, ether
|
|||
file arch/sun3/dev/if_le.c le
|
||||
file arch/sun3/dev/if_le_subr.c le
|
||||
|
||||
device zs at obio: tty
|
||||
device zs at obio: tty, lame_zs
|
||||
file arch/sun3/dev/zs.c zs needs-count
|
||||
|
||||
device clock at obio
|
||||
file arch/sun3/sun3/clock.c clock
|
||||
|
||||
# define scsi {}
|
||||
#
|
||||
# #device si at obio: scsi
|
||||
# #file arch/sun3/dev/si.c si
|
||||
# device si at obio: scsi
|
||||
# file arch/sun3/dev/scsi.c si
|
||||
#
|
||||
# device scsibus at scsi { target = -1, lun = -1 }
|
||||
# file arch/sun3/scsi/scsiconf.c scsibus needs-flag
|
||||
# file arch/sun3/scsi/scsi_base.c scsi
|
||||
# file arch/sun3/scsi/scsi_ioctl.c scsi
|
||||
#
|
||||
# device cd at scsibus: disk
|
||||
# file arch/sun3/scsi/cd.c cd needs-flag
|
||||
# major {cd=6}
|
||||
# device ch at scsibus: disk
|
||||
# file arch/sun3/scsi/ch.c ch needs-flag
|
||||
# device sd at scsibus: disk
|
||||
# file arch/sun3/scsi/sd.c sd needs-flag
|
||||
# major {sd=4}
|
||||
# device st at scsibus: tape
|
||||
# file arch/sun3/scsi/st.c st needs-flag
|
||||
# major {st=5}
|
||||
# file arch/sun3/scsi/uk.c uk needs-flag
|
||||
# file arch/sun3/scsi/su.c su needs-flag
|
||||
#
|
||||
device bwtwo at obmem: sunfb
|
||||
file arch/sun3/dev/bwtwo.c bwtwo
|
||||
|
||||
|
@ -60,3 +86,7 @@ file compat/sunos/sun_ioctl.c compat_sunos
|
|||
file compat/sunos/sun_misc.c compat_sunos
|
||||
file compat/sunos/sun_syscalls.c compat_sunos
|
||||
file compat/sunos/sun_sysent.c compat_sunos
|
||||
|
||||
file arch/sun3/dev/kbd.c lame_zs
|
||||
file arch/sun3/dev/event.c lame_zs
|
||||
file arch/sun3/dev/ms.c lame_zs
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
# $Id: std.sun3,v 1.5 1994/02/04 08:19:44 glass Exp $
|
||||
# $Id: std.sun3,v 1.6 1994/02/23 08:28:26 glass Exp $
|
||||
# Standard information for sun3's.
|
||||
|
||||
machine sun3 m68k
|
||||
|
||||
options NEWCONFIG
|
||||
options FPCOPROC
|
||||
|
||||
mainbus0 at root
|
||||
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)event.c 8.1 (Berkeley) 6/11/93
|
||||
*
|
||||
* from: Header: event.c,v 1.5 92/11/26 01:10:44 torek Exp (LBL)
|
||||
* $Id: event.c,v 1.1 1994/02/23 08:28:33 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internal `Firm_event' interface for the keyboard and mouse drivers.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include "vuid_event.h"
|
||||
#include "event_var.h"
|
||||
|
||||
/*
|
||||
* Initialize a firm_event queue.
|
||||
*/
|
||||
void
|
||||
ev_init(ev)
|
||||
register struct evvar *ev;
|
||||
{
|
||||
|
||||
ev->ev_get = ev->ev_put = 0;
|
||||
ev->ev_q = malloc((u_long)EV_QSIZE * sizeof(struct firm_event),
|
||||
M_DEVBUF, M_WAITOK);
|
||||
bzero((caddr_t)ev->ev_q, EV_QSIZE * sizeof(struct firm_event));
|
||||
}
|
||||
|
||||
/*
|
||||
* Tear down a firm_event queue.
|
||||
*/
|
||||
void
|
||||
ev_fini(ev)
|
||||
register struct evvar *ev;
|
||||
{
|
||||
|
||||
free(ev->ev_q, M_DEVBUF);
|
||||
}
|
||||
|
||||
/*
|
||||
* User-level interface: read, select.
|
||||
* (User cannot write an event queue.)
|
||||
*/
|
||||
int
|
||||
ev_read(ev, uio, flags)
|
||||
register struct evvar *ev;
|
||||
struct uio *uio;
|
||||
int flags;
|
||||
{
|
||||
int s, n, cnt, error;
|
||||
|
||||
/*
|
||||
* Make sure we can return at least 1.
|
||||
*/
|
||||
if (uio->uio_resid < sizeof(struct firm_event))
|
||||
return (EMSGSIZE); /* ??? */
|
||||
s = splev();
|
||||
while (ev->ev_get == ev->ev_put) {
|
||||
if (flags & IO_NDELAY) {
|
||||
splx(s);
|
||||
return (EWOULDBLOCK);
|
||||
}
|
||||
ev->ev_wanted = 1;
|
||||
error = tsleep((caddr_t)ev, PEVENT | PCATCH, "firm_event", 0);
|
||||
if (error) {
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Move firm_events from tail end of queue (there is at least one
|
||||
* there).
|
||||
*/
|
||||
if (ev->ev_put < ev->ev_get)
|
||||
cnt = EV_QSIZE - ev->ev_get; /* events in [get..QSIZE) */
|
||||
else
|
||||
cnt = ev->ev_put - ev->ev_get; /* events in [get..put) */
|
||||
splx(s);
|
||||
n = howmany(uio->uio_resid, sizeof(struct firm_event));
|
||||
if (cnt > n)
|
||||
cnt = n;
|
||||
error = uiomove((caddr_t)&ev->ev_q[ev->ev_get],
|
||||
cnt * sizeof(struct firm_event), uio);
|
||||
n -= cnt;
|
||||
/*
|
||||
* If we do not wrap to 0, used up all our space, or had an error,
|
||||
* stop. Otherwise move from front of queue to put index, if there
|
||||
* is anything there to move.
|
||||
*/
|
||||
if ((ev->ev_get = (ev->ev_get + cnt) % EV_QSIZE) != 0 ||
|
||||
n == 0 || error || (cnt = ev->ev_put) == 0)
|
||||
return (error);
|
||||
if (cnt > n)
|
||||
cnt = n;
|
||||
error = uiomove((caddr_t)&ev->ev_q[0],
|
||||
cnt * sizeof(struct firm_event), uio);
|
||||
ev->ev_get = cnt;
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
ev_select(ev, rw, p)
|
||||
register struct evvar *ev;
|
||||
int rw;
|
||||
struct proc *p;
|
||||
{
|
||||
int s = splev();
|
||||
|
||||
switch (rw) {
|
||||
|
||||
case FREAD:
|
||||
/* succeed if there is something to read */
|
||||
if (ev->ev_get != ev->ev_put) {
|
||||
splx(s);
|
||||
return (1);
|
||||
}
|
||||
selrecord(p, &ev->ev_sel);
|
||||
break;
|
||||
|
||||
case FWRITE:
|
||||
return (1); /* always fails => never blocks */
|
||||
}
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This software was developed by the Computer Systems Engineering group
|
||||
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
|
||||
* contributed to Berkeley.
|
||||
*
|
||||
* All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Lawrence Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)event_var.h 8.1 (Berkeley) 6/11/93
|
||||
*
|
||||
* from: Header: event_var.h,v 1.5 92/11/26 01:11:51 torek Exp (LBL)
|
||||
* $Id: event_var.h,v 1.1 1994/02/23 08:28:36 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Internal `Firm_event' interface for the keyboard and mouse drivers.
|
||||
* The drivers are expected not to place events in the queue above spltty(),
|
||||
* i.e., are expected to run off serial ports.
|
||||
*/
|
||||
|
||||
/* EV_QSIZE should be a power of two so that `%' is fast */
|
||||
#define EV_QSIZE 256 /* may need tuning; this uses 2k */
|
||||
|
||||
struct evvar {
|
||||
u_int ev_get; /* get (read) index (modified synchronously) */
|
||||
volatile u_int ev_put; /* put (write) index (modified by interrupt) */
|
||||
struct selinfo ev_sel; /* process selecting */
|
||||
struct proc *ev_io; /* process that opened queue (can get SIGIO) */
|
||||
char ev_wanted; /* wake up on input ready */
|
||||
char ev_async; /* send SIGIO on input ready */
|
||||
struct firm_event *ev_q;/* circular buffer (queue) of events */
|
||||
};
|
||||
|
||||
#define splev() spltty()
|
||||
|
||||
#define EV_WAKEUP(ev) { \
|
||||
selwakeup(&(ev)->ev_sel); \
|
||||
if ((ev)->ev_wanted) { \
|
||||
(ev)->ev_wanted = 0; \
|
||||
wakeup((caddr_t)(ev)); \
|
||||
} \
|
||||
if ((ev)->ev_async) \
|
||||
psignal((ev)->ev_io, SIGIO); \
|
||||
}
|
||||
|
||||
void ev_init __P((struct evvar *));
|
||||
void ev_fini __P((struct evvar *));
|
||||
int ev_read __P((struct evvar *, struct uio *, int));
|
||||
int ev_select __P((struct evvar *, int, struct proc *));
|
||||
|
||||
/*
|
||||
* PEVENT is set just above PSOCK, which is just above TTIPRI, on the
|
||||
* theory that mouse and keyboard `user' input should be quick.
|
||||
*/
|
||||
#define PEVENT 23
|
|
@ -89,7 +89,7 @@
|
|||
#include "if_le.h"
|
||||
#include "if_le_subr.h"
|
||||
|
||||
int ledebug = 1; /* console error messages */
|
||||
int ledebug = 0; /* console error messages */
|
||||
|
||||
int leintr(), leioctl(), ether_output();
|
||||
void lestart(), leinit();
|
||||
|
@ -335,7 +335,7 @@ leintr(unit)
|
|||
ler1 = le->sc_r1;
|
||||
LERDWR(le, ler1->ler1_rdp, stat);
|
||||
if (ledebug)
|
||||
printf("[le%d: stat %b]", unit, stat, LE_STATUS_BITS);
|
||||
printf("[le%d: stat %b]\n", unit, stat, LE_STATUS_BITS);
|
||||
if (stat & LE_SERR) {
|
||||
leerror(unit, stat);
|
||||
if (stat & LE_MERR) {
|
||||
|
|
|
@ -1,24 +1,57 @@
|
|||
#include "sys/param.h"
|
||||
#include "sys/systm.h"
|
||||
#include "sys/protosw.h"
|
||||
#include "sys/socket.h"
|
||||
#include "sys/device.h"
|
||||
#include "net/if.h"
|
||||
/*
|
||||
* Copyright (c) 1993 Adam Glass
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Adam Glass.
|
||||
* 4. The name of the Author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Adam Glass ``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 Adam Glass 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.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/dev/Attic/if_le_subr.c,v 1.3 1994/02/23 08:28:42 glass Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/device.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#ifdef INET
|
||||
#include "netinet/in.h"
|
||||
#include "netinet/in_systm.h"
|
||||
#include "netinet/in_var.h"
|
||||
#include "netinet/ip.h"
|
||||
#include "netinet/if_ether.h"
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#endif
|
||||
|
||||
#include "machine/autoconf.h"
|
||||
#include "machine/cpu.h"
|
||||
#include "machine/isr.h"
|
||||
#include "machine/mtpr.h"
|
||||
#include "machine/obio.h"
|
||||
#include "machine/idprom.h"
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/isr.h>
|
||||
#include <machine/mtpr.h>
|
||||
#include <machine/obio.h>
|
||||
#include <machine/idprom.h>
|
||||
|
||||
#include "bpfilter.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,669 @@
|
|||
/*
|
||||
* 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.1 (Berkeley) 6/11/93
|
||||
*
|
||||
* from: Header: kbd.c,v 1.16 92/11/26 01:28:44 torek Exp (LBL)
|
||||
* $Id: kbd.c,v 1.1 1994/02/23 08:28:43 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Keyboard driver (/dev/kbd -- note that we do not have minor numbers
|
||||
* [yet?]). Translates incoming bytes to ASCII or to `firm_events' and
|
||||
* passes them up to the appropriate reader.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/tty.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
|
||||
#include "vuid_event.h"
|
||||
#include "event_var.h"
|
||||
#include "kbd.h"
|
||||
#include "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 const 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 const u_char kbd_shifted[] = {
|
||||
/* 0 */ KEY_IGNORE, KEY_L1, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 4 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 8 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 12 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 16 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 20 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 24 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 28 */ KEY_IGNORE, '\033', '!', '@',
|
||||
/* 32 */ '#', '$', '%', '^',
|
||||
/* 36 */ '&', '*', '(', ')',
|
||||
/* 40 */ '_', '+', '~', '\b',
|
||||
/* 44 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 48 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 52 */ KEY_IGNORE, '\t', 'Q', 'W',
|
||||
/* 56 */ 'E', 'R', 'T', 'Y',
|
||||
/* 60 */ 'U', 'I', 'O', 'P',
|
||||
/* 64 */ '{', '}', '\177', KEY_IGNORE,
|
||||
/* 68 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 72 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 76 */ KEY_CONTROL, 'A', 'S', 'D',
|
||||
/* 80 */ 'F', 'G', 'H', 'J',
|
||||
/* 84 */ 'K', 'L', ':', '"',
|
||||
/* 88 */ '|', '\r', KEY_IGNORE, KEY_IGNORE,
|
||||
/* 92 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 96 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_LSHIFT,
|
||||
/* 100 */ 'Z', 'X', 'C', 'V',
|
||||
/* 104 */ 'B', 'N', 'M', '<',
|
||||
/* 108 */ '>', '?', KEY_RSHIFT, '\n',
|
||||
/* 112 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_IGNORE,
|
||||
/* 116 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_CAPSLOCK,
|
||||
/* 120 */ KEY_IGNORE, ' ', KEY_IGNORE, KEY_IGNORE,
|
||||
/* 124 */ KEY_IGNORE, KEY_IGNORE, KEY_IGNORE, KEY_ALLUP,
|
||||
};
|
||||
|
||||
/*
|
||||
* We need to remember the state of the keyboard's shift and control
|
||||
* keys, and we need a per-type translation table.
|
||||
*/
|
||||
struct kbd_state {
|
||||
const u_char *kbd_unshifted; /* unshifted keys */
|
||||
const u_char *kbd_shifted; /* shifted keys */
|
||||
const u_char *kbd_cur; /* current keys (either of the preceding) */
|
||||
union {
|
||||
char c[2]; /* left and right shift keys */
|
||||
short s; /* true => either shift key */
|
||||
} kbd_shift;
|
||||
#define kbd_lshift kbd_shift.c[0]
|
||||
#define kbd_rshift kbd_shift.c[1]
|
||||
#define kbd_anyshift kbd_shift.s
|
||||
char kbd_control; /* true => ctrl down */
|
||||
char kbd_click; /* true => keyclick enabled */
|
||||
char kbd_takeid; /* take next byte as ID */
|
||||
u_char kbd_id; /* a place to store the ID */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
} kbd_softc;
|
||||
|
||||
/* Prototypes */
|
||||
void kbd_ascii(struct tty *);
|
||||
void kbd_serial(struct tty *, void (*)(), void (*)());
|
||||
static void kbd_getid(void *);
|
||||
void kbd_reset(struct kbd_state *);
|
||||
static int kbd_translate(int, struct kbd_state *);
|
||||
void kbd_rint(int);
|
||||
int kbdopen(dev_t, int, int, struct proc *);
|
||||
int kbdclose(dev_t, int, int, struct proc *);
|
||||
int kbdread(dev_t, struct uio *, int);
|
||||
int kbdwrite(dev_t, struct uio *, int);
|
||||
int kbdioctl(dev_t, int, caddr_t, int, struct proc *);
|
||||
int kbdselect(dev_t, int, struct proc *);
|
||||
int kbd_docmd(int, int);
|
||||
|
||||
/*
|
||||
* Attach the console keyboard ASCII (up-link) interface.
|
||||
* This happens before kbd_serial.
|
||||
*/
|
||||
void
|
||||
kbd_ascii(struct tty *tp)
|
||||
{
|
||||
|
||||
kbd_softc.k_cons = tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach the console keyboard serial (down-link) interface.
|
||||
* We pick up the initial keyboard clock state here as well.
|
||||
*/
|
||||
void
|
||||
kbd_serial(struct tty *tp, void (*iopen)(), void (*iclose)())
|
||||
{
|
||||
register struct kbd_softc *k;
|
||||
register char *cp;
|
||||
|
||||
k = &kbd_softc;
|
||||
k->k_kbd = tp;
|
||||
k->k_open = iopen;
|
||||
k->k_close = iclose;
|
||||
|
||||
#if 0
|
||||
cp = getpropstring(optionsnode, "keyboard-click?");
|
||||
if (cp && strcmp(cp, "true") == 0)
|
||||
k->k_state.kbd_click = 1;
|
||||
#endif
|
||||
if (k->k_cons) {
|
||||
/*
|
||||
* We supply keys for /dev/console. Before we can
|
||||
* do so, we have to ``open'' the line. We also need
|
||||
* the type, got by sending a RESET down the line ...
|
||||
* but clists are not yet set up, so we use a timeout
|
||||
* to try constantly until we can get the ID. (gag)
|
||||
*/
|
||||
(*iopen)(tp); /* never to be closed */
|
||||
kbd_getid(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initial keyboard reset, to obtain ID and thus a translation table.
|
||||
* We have to try again and again until the tty subsystem works.
|
||||
*/
|
||||
static void
|
||||
kbd_getid(void *arg)
|
||||
{
|
||||
register struct kbd_softc *k;
|
||||
register struct tty *tp;
|
||||
register int retry;
|
||||
extern int cold; /* XXX */
|
||||
|
||||
k = &kbd_softc;
|
||||
if (k->k_state.kbd_cur != NULL)
|
||||
return;
|
||||
tp = k->k_kbd;
|
||||
if (cold || ttyoutput(KBD_CMD_RESET, tp) >= 0)
|
||||
retry = 1;
|
||||
else {
|
||||
(*tp->t_oproc)(tp);
|
||||
retry = 2 * hz;
|
||||
}
|
||||
timeout((timeout_t)kbd_getid, (caddr_t)NULL, retry);
|
||||
}
|
||||
|
||||
void
|
||||
kbd_reset(register struct kbd_state *ks)
|
||||
{
|
||||
/*
|
||||
* On first identification, wake up anyone waiting for type
|
||||
* and set up the table pointers.
|
||||
*/
|
||||
if (ks->kbd_unshifted == NULL) {
|
||||
wakeup((caddr_t)ks);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn keyboard up/down codes into ASCII.
|
||||
*/
|
||||
static int
|
||||
kbd_translate(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_rint(register int c)
|
||||
{
|
||||
register struct kbd_softc *k = &kbd_softc;
|
||||
register struct firm_event *fe;
|
||||
register int put;
|
||||
|
||||
/*
|
||||
* 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_takeid) {
|
||||
k->k_state.kbd_takeid = 0;
|
||||
k->k_state.kbd_id = c;
|
||||
kbd_reset(&k->k_state);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we have been reset, setup to grab the keyboard id next time */
|
||||
if (c == KBD_RESET) {
|
||||
k->k_state.kbd_takeid = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If /dev/kbd is not connected in event mode, but we are sending
|
||||
* data to /dev/console, translate and send upstream. Note that
|
||||
* we will get this while opening /dev/kbd if it is not already
|
||||
* open and we do not know its type.
|
||||
*/
|
||||
if (!k->k_evmode) {
|
||||
c = kbd_translate(c, &k->k_state);
|
||||
if (c >= 0 && k->k_cons != NULL)
|
||||
ttyinput(c, k->k_cons);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* IDLEs confuse the MIT X11R4 server badly, so we must drop them.
|
||||
* This is bad as it means the server will not automatically resync
|
||||
* on all-up IDLEs, but I did not drop them before, and the server
|
||||
* goes crazy when it comes time to blank the screen....
|
||||
*/
|
||||
if (c == KBD_IDLE)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Keyboard is generating events. Turn this keystroke into an
|
||||
* event and put it in the queue. If the queue is full, the
|
||||
* keystroke is lost (sorry!).
|
||||
*/
|
||||
put = k->k_events.ev_put;
|
||||
fe = &k->k_events.ev_q[put];
|
||||
put = (put + 1) % EV_QSIZE;
|
||||
if (put == k->k_events.ev_get) {
|
||||
log(LOG_WARNING, "keyboard event queue overflow\n"); /* ??? */
|
||||
return;
|
||||
}
|
||||
fe->id = KEY_CODE(c);
|
||||
fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN;
|
||||
fe->time = time;
|
||||
k->k_events.ev_put = put;
|
||||
EV_WAKEUP(&k->k_events);
|
||||
}
|
||||
|
||||
int
|
||||
kbdopen(dev_t dev, int flags, int mode, struct proc *p)
|
||||
{
|
||||
int s, error;
|
||||
|
||||
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.
|
||||
*/
|
||||
if (kbd_softc.k_cons == NULL)
|
||||
(*kbd_softc.k_open)(kbd_softc.k_kbd);
|
||||
error = 0;
|
||||
s = spltty();
|
||||
if (kbd_softc.k_state.kbd_cur == NULL) {
|
||||
(void) ttyoutput(KBD_CMD_RESET, kbd_softc.k_kbd);
|
||||
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_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_t dev, struct uio *uio, int flags)
|
||||
{
|
||||
|
||||
return (ev_read(&kbd_softc.k_events, uio, flags));
|
||||
}
|
||||
|
||||
/* this routine should not exist, but is convenient to write here for now */
|
||||
int
|
||||
kbdwrite(dev_t dev, struct uio *uio, int flags)
|
||||
{
|
||||
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
int
|
||||
kbdioctl(dev_t dev, int cmd, register caddr_t data, int flag, struct proc *p)
|
||||
{
|
||||
register struct kbd_softc *k = &kbd_softc;
|
||||
|
||||
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 kiockey *)data)->kio_station == 118) {
|
||||
/*
|
||||
* This is X11 asking if a type 3 keyboard is
|
||||
* really a type 3 keyboard. Say yes.
|
||||
*/
|
||||
((struct kiockey *)data)->kio_entry = HOLE;
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
|
||||
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 FIONBIO: /* we will remove this someday (soon???) */
|
||||
return (0);
|
||||
|
||||
case FIOASYNC:
|
||||
k->k_events.ev_async = *(int *)data != 0;
|
||||
return (0);
|
||||
|
||||
case TIOCSPGRP:
|
||||
if (*(int *)data != k->k_events.ev_io->p_pgid)
|
||||
return (EPERM);
|
||||
return (0);
|
||||
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
|
||||
/*
|
||||
* We identified the ioctl, but we do not handle it.
|
||||
*/
|
||||
return (EOPNOTSUPP); /* misuse, but what the heck */
|
||||
}
|
||||
|
||||
int
|
||||
kbdselect(dev_t dev, int rw, struct proc *p)
|
||||
{
|
||||
|
||||
return (ev_select(&kbd_softc.k_events, rw, p));
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a keyboard command; return 0 on success.
|
||||
* If `isuser', force a small delay before output if output queue
|
||||
* is flooding. (The keyboard runs at 1200 baud, or 120 cps.)
|
||||
*/
|
||||
int
|
||||
kbd_docmd(int cmd, int isuser)
|
||||
{
|
||||
register struct tty *tp = kbd_softc.k_kbd;
|
||||
register struct kbd_softc *k = &kbd_softc;
|
||||
int s;
|
||||
|
||||
if (tp == NULL)
|
||||
return (ENXIO); /* ??? */
|
||||
switch (cmd) {
|
||||
|
||||
case KBD_CMD_BELL:
|
||||
case KBD_CMD_NOBELL:
|
||||
/* Supported by type 2, 3, and 4 keyboards */
|
||||
break;
|
||||
|
||||
case KBD_CMD_CLICK:
|
||||
/* Unsupported by type 2 keyboards */
|
||||
if (k->k_state.kbd_id != KB_SUN2) {
|
||||
k->k_state.kbd_click = 1;
|
||||
break;
|
||||
}
|
||||
return (EINVAL);
|
||||
|
||||
case KBD_CMD_NOCLICK:
|
||||
/* Unsupported by type 2 keyboards */
|
||||
if (k->k_state.kbd_id != KB_SUN2) {
|
||||
k->k_state.kbd_click = 0;
|
||||
break;
|
||||
}
|
||||
return (EINVAL);
|
||||
|
||||
default:
|
||||
return (EINVAL); /* ENOTTY? EOPNOTSUPP? */
|
||||
}
|
||||
|
||||
if (isuser) {
|
||||
s = spltty();
|
||||
if (tp->t_outq.c_cc > 120)
|
||||
(void) tsleep((caddr_t)&lbolt, TTIPRI,
|
||||
ttyout, 0);
|
||||
splx(s);
|
||||
}
|
||||
if (ttyoutput(cmd, tp) >= 0)
|
||||
return (ENOSPC); /* ERESTART? */
|
||||
(*tp->t_oproc)(tp);
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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.h 8.1 (Berkeley) 6/11/93
|
||||
*
|
||||
* from: Header: kbd.h,v 1.5 92/11/26 01:15:33 torek Exp (LBL)
|
||||
* $Id: kbd.h,v 1.1 1994/02/23 08:28:45 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Keyboard `registers'. (This should be called kbd_reg.h but we need to
|
||||
* be compatible.)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Control codes sent from type 2, 3, and 4 keyboards.
|
||||
*
|
||||
* Note that KBD_RESET is followed by a keyboard ID, while KBD_IDLE is not.
|
||||
* 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_IDLE 0x7f /* keyboard `all keys are up' code */
|
||||
|
||||
/* Keyboard IDs */
|
||||
#define KB_SUN2 2 /* type 2 keyboard */
|
||||
#define KB_SUN3 3 /* type 3 keyboard */
|
||||
#define KB_SUN4 4 /* type 4 keyboard */
|
||||
|
||||
/* Key codes are in 0x00..0x7e; KBD_UP is set if the key goes up */
|
||||
#define KBD_KEYMASK 0x7f /* keyboard key mask */
|
||||
#define KBD_UP 0x80 /* keyboard `up' transition */
|
||||
|
||||
/* Keyboard codes needed to recognize the L1-A sequence */
|
||||
#define KBD_L1 1 /* keyboard code for `L1' key */
|
||||
#define KBD_A 77 /* keyboard code for `A' key */
|
||||
|
||||
/* Control codes sent to the various keyboards */
|
||||
#define KBD_CMD_RESET 1 /* reset keyboard */
|
||||
#define KBD_CMD_BELL 2 /* turn bell on */
|
||||
#define KBD_CMD_NOBELL 3 /* turn bell off */
|
||||
#define KBD_CMD_CLICK 10 /* turn keyclick on */
|
||||
#define KBD_CMD_NOCLICK 11 /* turn keyclick off */
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* @(#)kbio.h 8.1 (Berkeley) 6/11/93
|
||||
*
|
||||
* from: Header: kbio.h,v 1.4 92/11/26 01:16:32 torek Exp (LBL)
|
||||
* $Id: kbio.h,v 1.1 1994/02/23 08:28:47 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following is a minimal emulation of Sun's `kio' structures
|
||||
* and related operations necessary to make X11 happy (i.e., make it
|
||||
* compile, and make old X11 binaries run).
|
||||
*/
|
||||
|
||||
/*
|
||||
* The kiockey structure apparently gets and/or sets keyboard mappings.
|
||||
* It seems to be kind of useless, but X11 uses it (according to the
|
||||
* comments) to figure out when a Sun 386i has a type-4 keyboard but
|
||||
* claims to have a type-3 keyboard. We need just enough to cause the
|
||||
* appropriate ioctl to return the appropriate magic value.
|
||||
*
|
||||
* KIOCGETKEY fills in kio_entry from kio_station. Not sure what tablemask
|
||||
* is for; X sets it before the call, so it is not an output, but we do not
|
||||
* care anyway. KIOCSDIRECT is supposed to tell the kernel whether to send
|
||||
* keys to the console or to X; we just send them to X whenever the keyboard
|
||||
* is open at all. (XXX may need to change this later)
|
||||
*
|
||||
* Keyboard commands and types are defined in kbd.h as they are actually
|
||||
* real hardware commands and type numbers.
|
||||
*/
|
||||
struct kiockey {
|
||||
int kio_tablemask; /* whatever */
|
||||
u_char kio_station; /* key number */
|
||||
u_char kio_entry; /* HOLE if not present */
|
||||
char kio_text[10]; /* the silly escape sequences (unsupported) */
|
||||
};
|
||||
|
||||
#define HOLE 0x302 /* value for kio_entry to say `really type 3' */
|
||||
|
||||
#define KIOCTRANS _IOW('k', 0, int) /* set translation mode */
|
||||
/* (we only accept TR_UNTRANS_EVENT) */
|
||||
#define KIOCGETKEY _IOWR('k', 2, struct kiockey) /* 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 TR_UNTRANS_EVENT 3
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* from: Header: ms.c,v 1.5 92/11/26 01:28:47 torek Exp (LBL)
|
||||
* $Id: ms.c,v 1.1 1994/02/23 08:28:49 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mouse driver.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/tty.h>
|
||||
|
||||
#include "vuid_event.h"
|
||||
#include "event_var.h"
|
||||
|
||||
/*
|
||||
* Mouse state. A Mouse Systems mouse is a fairly simple device,
|
||||
* producing five-byte blobs of the form:
|
||||
*
|
||||
* b dx dy dx dy
|
||||
*
|
||||
* where b is the button state, encoded as 0x80|(~buttons)---there are
|
||||
* three buttons (4=left, 2=middle, 1=right)---and dx,dy are X and Y
|
||||
* delta values, none of which have are in [0x80..0x87]. (This lets
|
||||
* us sync up with the mouse after an error.)
|
||||
*/
|
||||
struct ms_softc {
|
||||
short ms_byteno; /* input byte number, for decode */
|
||||
char ms_mb; /* mouse button state */
|
||||
char ms_ub; /* user button state */
|
||||
int ms_dx; /* delta-x */
|
||||
int ms_dy; /* delta-y */
|
||||
struct tty *ms_mouse; /* downlink for output to mouse */
|
||||
void (*ms_open) __P((struct tty *)); /* enable dataflow */
|
||||
void (*ms_close) __P((struct tty *));/* disable dataflow */
|
||||
volatile int ms_ready; /* event queue is ready */
|
||||
struct evvar ms_events; /* event queue state */
|
||||
} ms_softc;
|
||||
|
||||
/*
|
||||
* Attach the mouse serial (down-link) interface.
|
||||
* Do we need to set it to 1200 baud, 8 bits?
|
||||
* Test by power cycling and not booting SunOS before BSD?
|
||||
*/
|
||||
void
|
||||
ms_serial(tp, iopen, iclose)
|
||||
struct tty *tp;
|
||||
void (*iopen)(), (*iclose)();
|
||||
{
|
||||
|
||||
ms_softc.ms_mouse = tp;
|
||||
ms_softc.ms_open = iopen;
|
||||
ms_softc.ms_close = iclose;
|
||||
}
|
||||
|
||||
void
|
||||
ms_rint(c)
|
||||
register int c;
|
||||
{
|
||||
register struct firm_event *fe;
|
||||
register struct ms_softc *ms = &ms_softc;
|
||||
register int mb, ub, d, get, put, any;
|
||||
static const char to_one[] = { 1, 2, 2, 4, 4, 4, 4 };
|
||||
static const int to_id[] = { MS_RIGHT, MS_MIDDLE, 0, MS_LEFT };
|
||||
|
||||
/*
|
||||
* Discard input if not ready. Drop sync on parity or framing
|
||||
* error; gain sync on button byte.
|
||||
*/
|
||||
if (ms->ms_ready == 0)
|
||||
return;
|
||||
if (c & (TTY_FE|TTY_PE)) {
|
||||
log(LOG_WARNING,
|
||||
"mouse input parity or framing error (0x%x)\n", c);
|
||||
ms->ms_byteno = -1;
|
||||
return;
|
||||
}
|
||||
if ((unsigned)(c - 0x80) < 8) /* if in 0x80..0x87 */
|
||||
ms->ms_byteno = 0;
|
||||
|
||||
/*
|
||||
* Run the decode loop, adding to the current information.
|
||||
* We add, rather than replace, deltas, so that if the event queue
|
||||
* fills, we accumulate data for when it opens up again.
|
||||
*/
|
||||
switch (ms->ms_byteno) {
|
||||
|
||||
case -1:
|
||||
return;
|
||||
|
||||
case 0:
|
||||
/* buttons */
|
||||
ms->ms_byteno = 1;
|
||||
ms->ms_mb = (~c) & 0x7;
|
||||
return;
|
||||
|
||||
case 1:
|
||||
/* first delta-x */
|
||||
ms->ms_byteno = 2;
|
||||
ms->ms_dx += (char)c;
|
||||
return;
|
||||
|
||||
case 2:
|
||||
/* first delta-y */
|
||||
ms->ms_byteno = 3;
|
||||
ms->ms_dy += (char)c;
|
||||
return;
|
||||
|
||||
case 3:
|
||||
/* second delta-x */
|
||||
ms->ms_byteno = 4;
|
||||
ms->ms_dx += (char)c;
|
||||
return;
|
||||
|
||||
case 4:
|
||||
/* second delta-x */
|
||||
ms->ms_byteno = -1; /* wait for button-byte again */
|
||||
ms->ms_dy += (char)c;
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("ms_rint");
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* We have at least one event (mouse button, delta-X, or
|
||||
* delta-Y; possibly all three, and possibly three separate
|
||||
* button events). Deliver these events until we are out
|
||||
* of changes or out of room. As events get delivered,
|
||||
* mark them `unchanged'.
|
||||
*/
|
||||
any = 0;
|
||||
get = ms->ms_events.ev_get;
|
||||
put = ms->ms_events.ev_put;
|
||||
fe = &ms->ms_events.ev_q[put];
|
||||
|
||||
/* NEXT prepares to put the next event, backing off if necessary */
|
||||
#define NEXT \
|
||||
if ((++put) % EV_QSIZE == get) { \
|
||||
put--; \
|
||||
goto out; \
|
||||
}
|
||||
/* ADVANCE completes the `put' of the event */
|
||||
#define ADVANCE \
|
||||
fe++; \
|
||||
if (put >= EV_QSIZE) { \
|
||||
put = 0; \
|
||||
fe = &ms->ms_events.ev_q[0]; \
|
||||
} \
|
||||
any = 1
|
||||
|
||||
mb = ms->ms_mb;
|
||||
ub = ms->ms_ub;
|
||||
while ((d = mb ^ ub) != 0) {
|
||||
/*
|
||||
* Mouse button change. Convert up to three changes
|
||||
* to the `first' change, and drop it into the event queue.
|
||||
*/
|
||||
NEXT;
|
||||
d = to_one[d - 1]; /* from 1..7 to {1,2,4} */
|
||||
fe->id = to_id[d - 1]; /* from {1,2,4} to ID */
|
||||
fe->value = mb & d ? VKEY_DOWN : VKEY_UP;
|
||||
fe->time = time;
|
||||
ADVANCE;
|
||||
ub ^= d;
|
||||
}
|
||||
if (ms->ms_dx) {
|
||||
NEXT;
|
||||
fe->id = LOC_X_DELTA;
|
||||
fe->value = ms->ms_dx;
|
||||
fe->time = time;
|
||||
ADVANCE;
|
||||
ms->ms_dx = 0;
|
||||
}
|
||||
if (ms->ms_dy) {
|
||||
NEXT;
|
||||
fe->id = LOC_Y_DELTA;
|
||||
fe->value = ms->ms_dy;
|
||||
fe->time = time;
|
||||
ADVANCE;
|
||||
ms->ms_dy = 0;
|
||||
}
|
||||
out:
|
||||
if (any) {
|
||||
ms->ms_ub = ub;
|
||||
ms->ms_events.ev_put = put;
|
||||
EV_WAKEUP(&ms->ms_events);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
msopen(dev, flags, mode, p)
|
||||
dev_t dev;
|
||||
int flags, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
int s, error;
|
||||
|
||||
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 */
|
||||
ms_softc.ms_ready = 1; /* start accepting events */
|
||||
(*ms_softc.ms_open)(ms_softc.ms_mouse);
|
||||
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;
|
||||
int cmd;
|
||||
register caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
int s;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case FIONBIO: /* we will remove this someday (soon???) */
|
||||
return (0);
|
||||
|
||||
case FIOASYNC:
|
||||
ms_softc.ms_events.ev_async = *(int *)data != 0;
|
||||
return (0);
|
||||
|
||||
case TIOCSPGRP:
|
||||
if (*(int *)data != ms_softc.ms_events.ev_io->p_pgid)
|
||||
return (EPERM);
|
||||
return (0);
|
||||
|
||||
case VUIDGFORMAT:
|
||||
/* we only do firm_events */
|
||||
*(int *)data = VUID_FIRM_EVENT;
|
||||
return (0);
|
||||
|
||||
case VUIDSFORMAT:
|
||||
if (*(int *)data != VUID_FIRM_EVENT)
|
||||
return (EINVAL);
|
||||
return (0);
|
||||
}
|
||||
return (ENOTTY);
|
||||
}
|
||||
|
||||
int
|
||||
msselect(dev, rw, p)
|
||||
dev_t dev;
|
||||
int rw;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (ev_select(&ms_softc.ms_events, rw, p));
|
||||
}
|
|
@ -1,67 +1,84 @@
|
|||
#include "sys/param.h"
|
||||
#include "sys/proc.h"
|
||||
#include "sys/systm.h"
|
||||
#include "sys/buf.h"
|
||||
#include "sys/ioctl.h"
|
||||
#include "sys/tty.h"
|
||||
#include "sys/file.h"
|
||||
#include "sys/conf.h"
|
||||
#include "device.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/tty.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/mon.h>
|
||||
|
||||
#include "machine/autoconf.h"
|
||||
#include "machine/mon.h"
|
||||
#include "../sun3/cons.h"
|
||||
#include "../sun3/interreg.h"
|
||||
|
||||
#include "prom.h"
|
||||
/*
|
||||
* cleanup:
|
||||
* get autoconfiguration right, right style
|
||||
* not a true serial driver but a tty driver, i.e no carrier
|
||||
* make sure start is non-blocking
|
||||
* add read support via timeouts
|
||||
*/
|
||||
|
||||
void promattach __P((struct device *, struct device *, void *));
|
||||
|
||||
struct prom_softc {
|
||||
struct device prom_dev;
|
||||
int prom_flags;
|
||||
int prom_nopen;
|
||||
struct tty *prom_t;
|
||||
struct device sc_dev;
|
||||
int sc_flags;
|
||||
int sc_nopen;
|
||||
struct tty *sc_tty;
|
||||
};
|
||||
|
||||
struct cfdriver promcd =
|
||||
{ NULL, "prom", always_match, promattach,
|
||||
DV_TTY, sizeof(struct prom_softc), 0};
|
||||
{ NULL, "prom", always_match, promattach, DV_TTY,
|
||||
sizeof(struct prom_softc), 0};
|
||||
|
||||
#define PROM_CHECK(unit) \
|
||||
if (unit >= promcd.cd_ndevs || (promcd.cd_devs[unit] == NULL)) \
|
||||
return ENXIO
|
||||
#define UNIT_TO_PROMP(unit) promcd.cd_devs[unit]
|
||||
#define UNIT_TO_PROM_SC(unit) promcd.cd_devs[unit]
|
||||
|
||||
int promopen __P((dev_t, int, int, struct proc *));
|
||||
int promclose __P((dev_t, int, int, struct proc *));
|
||||
int promread __P((dev_t, struct uio *, int));
|
||||
int promwrite __P((dev_t, struct uio *, int));
|
||||
int promioctl __P((dev_t, int, caddr_t, int, struct proc *));
|
||||
int promstop __P((struct tty *, int));
|
||||
|
||||
static int promparam __P((struct tty *, struct termios *));
|
||||
static void promstart __P((struct tty *));
|
||||
static void promreceive __P((caddr_t));
|
||||
|
||||
void promattach(parent, self, args)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *args;
|
||||
{
|
||||
struct prom_softc *promp = (struct prom_softc *) self;
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void promstart __P((struct tty *));
|
||||
|
||||
int promopen(dev, flag, mode, p)
|
||||
dev_t dev;
|
||||
int flag, mode;
|
||||
struct proc *p;
|
||||
{
|
||||
struct tty *tp;
|
||||
struct prom_softc *promp;
|
||||
int unit;
|
||||
int s,error=0;
|
||||
struct prom_softc *prom_sc;
|
||||
int unit, s, result;
|
||||
|
||||
unit = minor(dev);
|
||||
PROM_CHECK(unit);
|
||||
promp = UNIT_TO_PROMP(unit);
|
||||
if (!promp->prom_t)
|
||||
tp = promp->prom_t = ttymalloc();
|
||||
prom_sc = UNIT_TO_PROM_SC(unit);
|
||||
if (prom_sc->sc_tty == NULL)
|
||||
tp = prom_sc->sc_tty = ttymalloc();
|
||||
else
|
||||
tp = promp->prom_t;
|
||||
tp = prom_sc->sc_tty;
|
||||
tp->t_addr = (caddr_t) tp;
|
||||
tp->t_oproc = promstart;
|
||||
tp->t_param = promparam;
|
||||
tp->t_dev = dev;
|
||||
if ((tp->t_state & TS_ISOPEN) == 0) {
|
||||
tp->t_state |= TS_WOPEN;
|
||||
|
@ -73,23 +90,17 @@ int promopen(dev, flag, mode, p)
|
|||
tp->t_lflag = TTYDEF_LFLAG;
|
||||
tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
|
||||
}
|
||||
promparam(tp, &tp->t_termios);
|
||||
ttsetwater(tp);
|
||||
}
|
||||
else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
|
||||
return (EBUSY);
|
||||
|
||||
s = spltty();
|
||||
while ((flag & O_NONBLOCK) == 0 && (tp->t_cflag &CLOCAL) == 0 &&
|
||||
(tp->t_state & TS_CARR_ON) == 0) {
|
||||
tp->t_state |= TS_WOPEN;
|
||||
if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
|
||||
ttopen, 0))
|
||||
break;
|
||||
}
|
||||
splx(s);
|
||||
if (error == 0)
|
||||
error = (*linesw[tp->t_line].l_open)(dev, tp);
|
||||
return (error);
|
||||
return EBUSY;
|
||||
tp->t_state |= TS_CARR_ON;
|
||||
result = (*linesw[tp->t_line].l_open)(dev, tp);
|
||||
if (result)
|
||||
return result;
|
||||
timeout((timeout_t) promreceive, (caddr_t) tp, hz/2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
promclose(dev, flag, mode, p)
|
||||
|
@ -99,15 +110,14 @@ promclose(dev, flag, mode, p)
|
|||
{
|
||||
struct tty *tp;
|
||||
int unit;
|
||||
struct prom_softc *promp;
|
||||
struct prom_softc *prom_sc;
|
||||
|
||||
unit = minor(dev);
|
||||
PROM_CHECK(unit);
|
||||
promp = UNIT_TO_PROMP(unit);
|
||||
tp = promp->prom_t;
|
||||
prom_sc = UNIT_TO_PROM_SC(unit);
|
||||
tp = prom_sc->sc_tty;
|
||||
|
||||
(*linesw[tp->t_line].l_close)(tp, flag);
|
||||
ttyclose(tp);
|
||||
return 0;
|
||||
return ttyclose(tp);
|
||||
}
|
||||
|
||||
promread(dev, uio, flag)
|
||||
|
@ -116,12 +126,12 @@ promread(dev, uio, flag)
|
|||
{
|
||||
int unit;
|
||||
register struct tty *tp;
|
||||
struct prom_softc *promp;
|
||||
struct prom_softc *prom_sc;
|
||||
|
||||
unit = minor(dev);
|
||||
PROM_CHECK(unit);
|
||||
promp = UNIT_TO_PROMP(unit);
|
||||
tp = promp->prom_t;
|
||||
prom_sc = UNIT_TO_PROM_SC(unit);
|
||||
|
||||
tp = prom_sc->sc_tty;
|
||||
return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
|
||||
}
|
||||
promwrite(dev, uio, flag)
|
||||
|
@ -130,31 +140,30 @@ promwrite(dev, uio, flag)
|
|||
{
|
||||
int unit;
|
||||
register struct tty *tp;
|
||||
struct prom_softc *promp;
|
||||
struct prom_softc *prom_sc;
|
||||
|
||||
unit = minor(dev);
|
||||
PROM_CHECK(unit);
|
||||
promp = UNIT_TO_PROMP(unit);
|
||||
tp = promp->prom_t;
|
||||
|
||||
prom_sc = UNIT_TO_PROM_SC(unit);
|
||||
|
||||
tp = prom_sc->sc_tty;
|
||||
return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
|
||||
}
|
||||
|
||||
int promioctl(dev, cmd, data, flag)
|
||||
int promioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
int cmd;
|
||||
caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
int unit;
|
||||
register struct tty *tp;
|
||||
struct prom_softc *promp;
|
||||
struct prom_softc *prom_sc;
|
||||
int error;
|
||||
|
||||
unit = minor(dev);
|
||||
PROM_CHECK(unit);
|
||||
promp = UNIT_TO_PROMP(unit);
|
||||
tp = promp->prom_t;
|
||||
prom_sc = UNIT_TO_PROM_SC(unit);
|
||||
tp = prom_sc->sc_tty;
|
||||
|
||||
error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
|
||||
if (error >= 0)
|
||||
|
@ -162,22 +171,19 @@ int promioctl(dev, cmd, data, flag)
|
|||
error = ttioctl(tp, cmd, data, flag);
|
||||
if (error >= 0)
|
||||
return error;
|
||||
|
||||
switch (cmd) {
|
||||
default:
|
||||
return ENOTTY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ENOTTY;
|
||||
}
|
||||
|
||||
void promstart(tp)
|
||||
struct tty *tp;
|
||||
{
|
||||
int s;
|
||||
int c;
|
||||
int s, c, count;
|
||||
u_char outbuf[50];
|
||||
u_char *bufp;
|
||||
|
||||
s = spltty();
|
||||
if (tp->t_state & (TS_BUSY | TS_TTSTOP)) goto out;
|
||||
if (tp->t_state & (TS_BUSY|TS_TTSTOP|TS_TIMEOUT)) goto out;
|
||||
tp->t_state |= TS_BUSY;
|
||||
if (tp->t_outq.c_cc <= tp->t_lowat) {
|
||||
if (tp->t_state & TS_ASLEEP) {
|
||||
tp->t_state &=~ TS_ASLEEP;
|
||||
|
@ -185,30 +191,64 @@ void promstart(tp)
|
|||
}
|
||||
selwakeup(&tp->t_wsel);
|
||||
}
|
||||
if (tp->t_outq.c_cc == 0)
|
||||
goto out;
|
||||
tp->t_state |= TS_BUSY;
|
||||
c = getc(&tp->t_outq);
|
||||
mon_putchar(c);
|
||||
count = q_to_b(&tp->t_outq, outbuf, 49);
|
||||
if (count) {
|
||||
outbuf[count] = '\0';
|
||||
(void) splhigh();
|
||||
mon_printf("%s", outbuf);
|
||||
(void) spltty();
|
||||
}
|
||||
tp->t_state &= ~TS_BUSY;
|
||||
out:
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop output on a line.
|
||||
*/
|
||||
promstop(tp, flag)
|
||||
register struct tty *tp;
|
||||
static int promparam(tp, t)
|
||||
struct tty *tp;
|
||||
struct termios *t;
|
||||
{
|
||||
register int s;
|
||||
struct prom_softc *prom_sc;
|
||||
|
||||
s = spltty();
|
||||
if (tp->t_state & TS_BUSY) {
|
||||
if ((tp->t_state&TS_TTSTOP)==0)
|
||||
tp->t_state |= TS_FLUSH;
|
||||
}
|
||||
splx(s);
|
||||
if (!t->c_ispeed || (t->c_ispeed != t->c_ospeed))
|
||||
return EINVAL;
|
||||
tp->t_ispeed = t->c_ispeed;
|
||||
tp->t_ospeed = t->c_ospeed;
|
||||
tp->t_cflag = t->c_cflag;
|
||||
return 0;
|
||||
}
|
||||
static void promreceive(arg)
|
||||
caddr_t arg;
|
||||
{
|
||||
struct tty *tp;
|
||||
int c, s;
|
||||
|
||||
tp = (struct tty *) arg;
|
||||
|
||||
s = spltty();
|
||||
if (tp->t_state & TS_ISOPEN) {
|
||||
if ((tp->t_state & TS_BUSY) == 0) {
|
||||
extern unsigned int orig_nmi_vector;
|
||||
extern int nmi_intr();
|
||||
|
||||
set_clk_mode(0,IREG_CLOCK_ENAB_7|IREG_CLOCK_ENAB_5,0);
|
||||
isr_add_custom(7, orig_nmi_vector);
|
||||
set_clk_mode(IREG_CLOCK_ENAB_7,0,1);
|
||||
c = mon_may_getchar();
|
||||
set_clk_mode(0,IREG_CLOCK_ENAB_7|IREG_CLOCK_ENAB_5,0);
|
||||
isr_add_custom(7, nmi_intr);
|
||||
set_clk_mode(IREG_CLOCK_ENAB_5,0,1);
|
||||
if (c != -1) {
|
||||
(*linesw[tp->t_line].l_rint)(c, tp);
|
||||
}
|
||||
}
|
||||
timeout((timeout_t) promreceive, (caddr_t) tp, hz/3);
|
||||
}
|
||||
else {
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* prom console support */
|
||||
|
||||
|
@ -223,7 +263,7 @@ promcnprobe(cp)
|
|||
break;
|
||||
|
||||
cp->cn_dev = makedev(prommajor, 0);
|
||||
cp->cn_pri = CN_NORMAL; /* will always exist but you don't
|
||||
cp->cn_pri = CN_INTERNAL; /* will always exist but you don't
|
||||
* want to use it unless you have to
|
||||
*/
|
||||
}
|
||||
|
@ -248,7 +288,11 @@ promcnputc(dev, c)
|
|||
dev_t dev;
|
||||
int c;
|
||||
{
|
||||
int s;
|
||||
|
||||
s = splhigh();
|
||||
if (minor(dev) != 0)
|
||||
mon_printf("non unit 0 prom console???\n");
|
||||
mon_putchar(c);
|
||||
splx(s);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Mach Operating System
|
||||
* Copyright (c) 1991,1990,1989 Carnegie Mellon University
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and its
|
||||
* documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
/*
|
||||
* HISTORY
|
||||
* $Log: scsi_5380.h,v $
|
||||
* Revision 1.1 1994/02/23 08:28:53 glass
|
||||
* boots, presents shell prompt, and doesn't crash immediately
|
||||
*
|
||||
* Revision 1.1 94/02/22 23:38:09 glass
|
||||
* hey, it gets to a shell prompt
|
||||
*
|
||||
* Revision 2.3 91/08/24 12:25:10 af
|
||||
* Moved padding of regmap in impl file.
|
||||
* [91/08/02 04:22:39 af]
|
||||
*
|
||||
* Revision 2.2 91/06/19 16:28:35 rvb
|
||||
* From the NCR data sheets
|
||||
* "NCR 5380 Family, SCSI Protocol Controller Data Manual"
|
||||
* NCR Microelectronics Division, Colorado Spring, 6/98 T01891L
|
||||
* [91/04/21 af]
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* File: scsi_5380.h
|
||||
* Author: Alessandro Forin, Carnegie Mellon University
|
||||
* Date: 5/91
|
||||
*
|
||||
* Defines for the NCR 5380 (SCSI chip), aka Am5380
|
||||
*/
|
||||
|
||||
/*
|
||||
* Register map
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned char sci_data; /* r: Current data */
|
||||
#define sci_odata sci_data /* w: Out data */
|
||||
volatile unsigned char sci_icmd; /* rw: Initiator command */
|
||||
volatile unsigned char sci_mode; /* rw: Mode */
|
||||
volatile unsigned char sci_tcmd; /* rw: Target command */
|
||||
volatile unsigned char sci_bus_csr; /* r: Bus Status */
|
||||
#define sci_sel_enb sci_bus_csr /* w: Select enable */
|
||||
volatile unsigned char sci_csr; /* r: Status */
|
||||
#define sci_dma_send sci_csr /* w: Start dma send data */
|
||||
volatile unsigned char sci_idata; /* r: Input data */
|
||||
#define sci_trecv sci_idata /* w: Start dma receive, target */
|
||||
volatile unsigned char sci_iack; /* r: Interrupt Acknowledge */
|
||||
#define sci_irecv sci_iack /* w: Start dma receive, initiator */
|
||||
} sci_regmap_t;
|
||||
|
||||
|
||||
/*
|
||||
* Initiator command register
|
||||
*/
|
||||
|
||||
#define SCI_ICMD_DATA 0x01 /* rw: Assert data bus */
|
||||
#define SCI_ICMD_ATN 0x02 /* rw: Assert ATN signal */
|
||||
#define SCI_ICMD_SEL 0x04 /* rw: Assert SEL signal */
|
||||
#define SCI_ICMD_BSY 0x08 /* rw: Assert BSY signal */
|
||||
#define SCI_ICMD_ACK 0x10 /* rw: Assert ACK signal */
|
||||
#define SCI_ICMD_LST 0x20 /* r: Lost arbitration */
|
||||
#define SCI_ICMD_DIFF SCI_ICMD_LST /* w: Differential cable */
|
||||
#define SCI_ICMD_AIP 0x40 /* r: Arbitration in progress */
|
||||
#define SCI_ICMD_TEST SCI_ICMD_AIP /* w: Test mode */
|
||||
#define SCI_ICMD_RST 0x80 /* rw: Assert RST signal */
|
||||
|
||||
|
||||
/*
|
||||
* Mode register
|
||||
*/
|
||||
|
||||
#define SCI_MODE_ARB 0x01 /* rw: Start arbitration */
|
||||
#define SCI_MODE_DMA 0x02 /* rw: Enable DMA xfers */
|
||||
#define SCI_MODE_MONBSY 0x04 /* rw: Monitor BSY signal */
|
||||
#define SCI_MODE_DMA_IE 0x08 /* rw: Enable DMA complete interrupt */
|
||||
#define SCI_MODE_PERR_IE 0x10 /* rw: Interrupt on parity errors */
|
||||
#define SCI_MODE_PAR_CHK 0x20 /* rw: Check parity */
|
||||
#define SCI_MODE_TARGET 0x40 /* rw: Target mode (Initiator if 0) */
|
||||
#define SCI_MODE_BLOCKDMA 0x80 /* rw: Block-mode DMA handshake (MBZ) */
|
||||
|
||||
|
||||
/*
|
||||
* Target command register
|
||||
*/
|
||||
|
||||
#define SCI_TCMD_IO 0x01 /* rw: Assert I/O signal */
|
||||
#define SCI_TCMD_CD 0x02 /* rw: Assert C/D signal */
|
||||
#define SCI_TCMD_MSG 0x04 /* rw: Assert MSG signal */
|
||||
#define SCI_TCMD_PHASE_MASK 0x07 /* r: Mask for current bus phase */
|
||||
#define SCI_TCMD_REQ 0x08 /* rw: Assert REQ signal */
|
||||
#define SCI_TCMD_LAST_SENT 0x80 /* ro: Last byte was xferred
|
||||
* (not on 5380/1) */
|
||||
|
||||
#define SCI_PHASE(x) SCSI_PHASE(x)
|
||||
|
||||
/*
|
||||
* Current (SCSI) Bus status
|
||||
*/
|
||||
|
||||
#define SCI_BUS_DBP 0x01 /* r: Data Bus parity */
|
||||
#define SCI_BUS_SEL 0x02 /* r: SEL signal */
|
||||
#define SCI_BUS_IO 0x04 /* r: I/O signal */
|
||||
#define SCI_BUS_CD 0x08 /* r: C/D signal */
|
||||
#define SCI_BUS_MSG 0x10 /* r: MSG signal */
|
||||
#define SCI_BUS_REQ 0x20 /* r: REQ signal */
|
||||
#define SCI_BUS_BSY 0x40 /* r: BSY signal */
|
||||
#define SCI_BUS_RST 0x80 /* r: RST signal */
|
||||
|
||||
#define SCI_CUR_PHASE(x) SCSI_PHASE((x)>>2)
|
||||
|
||||
/*
|
||||
* Bus and Status register
|
||||
*/
|
||||
|
||||
#define SCI_CSR_ACK 0x01 /* r: ACK signal */
|
||||
#define SCI_CSR_ATN 0x02 /* r: ATN signal */
|
||||
#define SCI_CSR_DISC 0x04 /* r: Disconnected (BSY==0) */
|
||||
#define SCI_CSR_PHASE_MATCH 0x08 /* r: Bus and SCI_TCMD match */
|
||||
#define SCI_CSR_INT 0x10 /* r: Interrupt request */
|
||||
#define SCI_CSR_PERR 0x20 /* r: Parity error */
|
||||
#define SCI_CSR_DREQ 0x40 /* r: DMA request */
|
||||
#define SCI_CSR_DONE 0x80 /* r: DMA count is zero */
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*-
|
||||
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
|
||||
* Michael L. Finch, Bradley A. Grantham, and
|
||||
* Lawrence A. Kesteloot
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Alice Group.
|
||||
* 4. The names of the Alice Group or any of its members may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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.
|
||||
*
|
||||
* $Id: scsi_defs.h,v 1.1 1994/02/23 08:28:55 glass Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_DEFS_H
|
||||
#define _SCSI_DEFS_H
|
||||
|
||||
#define SCSI_PHASE_DATA_OUT 0x0
|
||||
#define SCSI_PHASE_DATA_IN 0x1
|
||||
#define SCSI_PHASE_CMD 0x2
|
||||
#define SCSI_PHASE_STATUS 0x3
|
||||
#define SCSI_PHASE_UNSPEC1 0x4
|
||||
#define SCSI_PHASE_UNSPEC2 0x5
|
||||
#define SCSI_PHASE_MESSAGE_OUT 0x6
|
||||
#define SCSI_PHASE_MESSAGE_IN 0x7
|
||||
|
||||
#define SCSI_PHASE(x) ((x)&0x7)
|
||||
|
||||
/* These should be fixed up. */
|
||||
|
||||
#define SCSI_RET_SUCCESS 0
|
||||
#define SCSI_RET_RETRY 1
|
||||
#define SCSI_RET_DEVICE_DOWN 2
|
||||
#define SCSI_RET_COMMAND_FAIL 3
|
||||
|
||||
#endif
|
|
@ -0,0 +1,968 @@
|
|||
/*
|
||||
* Copyright (C) 1994 Adam Glass
|
||||
* Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
|
||||
* Michael L. Finch, Bradley A. Grantham, and
|
||||
* Lawrence A. Kesteloot
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Alice Group.
|
||||
* 4. The names of the Alice Group or any of its members may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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.
|
||||
*
|
||||
* $Id: si.c,v 1.1 1994/02/23 08:28:56 glass Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#define PSEUDO_DMA 1
|
||||
|
||||
static int pdebug=0;
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/autoconf.h>
|
||||
#include <machine/isr.h>
|
||||
#include <machine/mtpr.h>
|
||||
#include <machine/obio.h>
|
||||
|
||||
#include "../scsi/scsi_all.h"
|
||||
#include "../scsi/scsi_debug.h"
|
||||
#include "../scsi/scsiconf.h"
|
||||
#include "scsi_defs.h"
|
||||
#include "scsi_5380.h"
|
||||
|
||||
#define SCI_PHASE_DISC 0 /* sort of ... */
|
||||
#define SCI_CLR_INTR(regs) {register int temp = regs->sci_iack;}
|
||||
#define SCI_ACK(ptr,phase) (ptr)->sci_tcmd = (phase)
|
||||
#define SCSI_TIMEOUT_VAL 10000000
|
||||
#define WAIT_FOR_NOT_REQ(ptr) { \
|
||||
int scsi_timeout = SCSI_TIMEOUT_VAL; \
|
||||
while ( ((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
|
||||
((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
|
||||
((ptr)->sci_bus_csr & SCI_BUS_REQ) && \
|
||||
(--scsi_timeout) ); \
|
||||
if (!scsi_timeout) { \
|
||||
printf("scsi timeout--WAIT_FOR_NOT_REQ---scsi.c, line %d.\n", __LINE__); \
|
||||
goto scsi_timeout_error; \
|
||||
} \
|
||||
}
|
||||
#define WAIT_FOR_REQ(ptr) { \
|
||||
int scsi_timeout = SCSI_TIMEOUT_VAL; \
|
||||
while ( (((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
|
||||
(((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
|
||||
(((ptr)->sci_bus_csr & SCI_BUS_REQ) == 0) && \
|
||||
(--scsi_timeout) ); \
|
||||
if (!scsi_timeout) { \
|
||||
printf("scsi timeout--WAIT_FOR_REQ---scsi.c, line %d.\n", __LINE__); \
|
||||
goto scsi_timeout_error; \
|
||||
} \
|
||||
}
|
||||
#define WAIT_FOR_BSY(ptr) { \
|
||||
int scsi_timeout = SCSI_TIMEOUT_VAL; \
|
||||
while ( (((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
|
||||
(((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
|
||||
(((ptr)->sci_bus_csr & SCI_BUS_BSY) == 0) && \
|
||||
(--scsi_timeout) ); \
|
||||
if (!scsi_timeout) { \
|
||||
printf("scsi timeout--WAIT_FOR_BSY---scsi.c, line %d.\n", __LINE__); \
|
||||
goto scsi_timeout_error; \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef DDB
|
||||
int Debugger();
|
||||
#else
|
||||
#define Debugger() panic("Should call Debugger here (sun3/dev/scsi.c).")
|
||||
#endif
|
||||
|
||||
struct ncr5380_softc {
|
||||
struct device sc_dev;
|
||||
void *sc_regs;
|
||||
int sc_adapter_target;
|
||||
struct scsi_link sc_link;
|
||||
};
|
||||
|
||||
#if 0
|
||||
In your dreams dude...
|
||||
/* From Guide to Mac II family hardware, p. 137 */
|
||||
static volatile sci_padded_regmap_t *ncr = (sci_regmap_t *) 0x50F10000;
|
||||
static volatile long *sci_4byte_addr= (long *) 0x50F06000;
|
||||
static volatile u_char *sci_1byte_addr=(u_char *) 0x50F12000;
|
||||
#endif
|
||||
|
||||
static unsigned int ncr5380_adapter_info(struct ncr5380_softc *ncr5380);
|
||||
static void ncr5380_minphys(struct buf *bp);
|
||||
static int ncr5380_scsi_cmd(struct scsi_xfer *xs);
|
||||
|
||||
static int ncr5380_show_scsi_cmd(struct scsi_xfer *xs);
|
||||
static int ncr5380_reset_target(int adapter, int target);
|
||||
static int ncr5380_poll(int adapter, int timeout);
|
||||
static int ncr5380_send_cmd(struct scsi_xfer *xs);
|
||||
|
||||
extern void ncr5380_intr(int adapter);
|
||||
extern void spinwait(int);
|
||||
|
||||
static void delay(int);
|
||||
|
||||
static int scsi_gen(int adapter, int id, int lun,
|
||||
struct scsi_generic *cmd, int cmdlen,
|
||||
void *databuf, int datalen);
|
||||
static int scsi_group0(int adapter, int id, int lun,
|
||||
int opcode, int addr, int len,
|
||||
int flags, caddr_t databuf, int datalen);
|
||||
|
||||
static char scsi_name[] = "si";
|
||||
|
||||
struct scsi_adapter ncr5380_switch = {
|
||||
ncr5380_scsi_cmd, /* scsi_cmd() */
|
||||
ncr5380_minphys, /* scsi_minphys() */
|
||||
0, /* open_target_lu() */
|
||||
0, /* close_target_lu() */
|
||||
ncr5380_adapter_info, /* adapter_info() */
|
||||
scsi_name, /* name */
|
||||
{0, 0} /* spare[3] */
|
||||
};
|
||||
|
||||
/* This is copied from julian's bt driver */
|
||||
/* "so we have a default dev struct for our link struct." */
|
||||
struct scsi_device ncr_dev = {
|
||||
NULL, /* Use default error handler. */
|
||||
NULL, /* have a queue, served by this (?) */
|
||||
NULL, /* have no async handler. */
|
||||
NULL, /* Use default "done" routine. */
|
||||
"si",
|
||||
0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
extern int matchbyname();
|
||||
static int ncrprobe();
|
||||
static void ncrattach();
|
||||
|
||||
struct cfdriver ncrcd =
|
||||
{ NULL, "si", ncrprobe, ncrattach,
|
||||
DV_DULL, sizeof(struct ncr5380_softc), NULL, 0 };
|
||||
|
||||
static int
|
||||
ncr_print(aux, name)
|
||||
void *aux;
|
||||
char *name;
|
||||
{
|
||||
/* printf("%s: (sc_link = 0x%x)", name, (int) aux);
|
||||
return UNCONF;*/
|
||||
}
|
||||
|
||||
static int
|
||||
ncrprobe(parent, cf, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *cf;
|
||||
void *aux;
|
||||
{
|
||||
caddr_t si_addr;
|
||||
struct obio_cf_loc *obio_loc = (struct obio_cf_loc *) CFDATA_LOC(cf);
|
||||
|
||||
si_addr = OBIO_DEFAULT_PARAM(caddr_t, obio_loc->obio_addr, OBIO_NCR_SCSI);
|
||||
return /* !obio_probe_byte(si_addr)*/ 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ncrattach(parent, self, aux)
|
||||
struct device *parent, *self;
|
||||
void *aux;
|
||||
{
|
||||
caddr_t dvma_malloc(), si_addr;
|
||||
int level, ncr_intr(), unit = DEVICE_UNIT(self);
|
||||
struct ncr5380_softc *ncr5380 = (struct ncr5380_softc *) self;
|
||||
struct obio_cf_loc *obio_loc = OBIO_LOC(self);
|
||||
|
||||
si_addr = OBIO_DEFAULT_PARAM(caddr_t, obio_loc->obio_addr, OBIO_NCR_SCSI);
|
||||
ncr5380->sc_regs = (sci_regmap_t *)
|
||||
obio_alloc(si_addr, OBIO_AMD_ETHER_SIZE, OBIO_WRITE);
|
||||
|
||||
level = OBIO_DEFAULT_PARAM(int, obio_loc->obio_level, 3);
|
||||
|
||||
ncr5380->sc_link.scsibus = unit;
|
||||
ncr5380->sc_link.adapter_targ = 7;
|
||||
ncr5380->sc_link.adapter = &ncr5380_switch;
|
||||
ncr5380->sc_link.device = &ncr_dev;
|
||||
|
||||
obio_print(si_addr, level);
|
||||
printf("\n");
|
||||
|
||||
config_found(self, &(ncr5380->sc_link), ncr_print);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ncr5380_adapter_info(struct ncr5380_softc *ncr5380)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define MIN_PHYS 65536 /*BARF!!!!*/
|
||||
static void
|
||||
ncr5380_minphys(struct buf *bp)
|
||||
{
|
||||
if (bp->b_bcount > MIN_PHYS) {
|
||||
printf("Uh-oh... ncr5380_minphys setting bp->b_bcount = %x.\n", MIN_PHYS);
|
||||
bp->b_bcount = MIN_PHYS;
|
||||
}
|
||||
}
|
||||
#undef MIN_PHYS
|
||||
|
||||
static int
|
||||
ncr5380_scsi_cmd(struct scsi_xfer *xs)
|
||||
{
|
||||
int flags, s, r;
|
||||
|
||||
flags = xs->flags;
|
||||
if (xs->bp) flags |= (SCSI_NOSLEEP);
|
||||
if ( flags & ITSDONE ) {
|
||||
printf("Already done?");
|
||||
xs->flags &= ~ITSDONE;
|
||||
}
|
||||
if ( ! ( flags & INUSE ) ) {
|
||||
printf("Not in use?");
|
||||
xs->flags |= INUSE;
|
||||
}
|
||||
|
||||
if ( flags & SCSI_RESET ) {
|
||||
printf("flags & SCSIRESET.\n");
|
||||
if ( ! ( flags & SCSI_NOSLEEP ) ) {
|
||||
s = splbio();
|
||||
ncr5380_reset_target(xs->sc_link->scsibus, xs->sc_link->target);
|
||||
splx(s);
|
||||
return(SUCCESSFULLY_QUEUED);
|
||||
} else {
|
||||
ncr5380_reset_target(xs->sc_link->scsibus, xs->sc_link->target);
|
||||
if (ncr5380_poll(xs->sc_link->scsibus, xs->timeout)) {
|
||||
return (HAD_ERROR);
|
||||
}
|
||||
return (COMPLETE);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* OK. Now that that's over with, let's pack up that
|
||||
* SCSI puppy and send it off. If we can, we'll just
|
||||
* queue and go; otherwise, we'll wait for the command
|
||||
* to finish.
|
||||
if ( ! ( flags & SCSI_NOSLEEP ) ) {
|
||||
s = splbio();
|
||||
ncr5380_send_cmd(xs);
|
||||
splx(s);
|
||||
return(SUCCESSFULLY_QUEUED);
|
||||
}
|
||||
*/
|
||||
|
||||
r = ncr5380_send_cmd(xs);
|
||||
xs->flags |= ITSDONE;
|
||||
scsi_done(xs);
|
||||
switch(r) {
|
||||
case COMPLETE: case SUCCESSFULLY_QUEUED:
|
||||
r = SUCCESSFULLY_QUEUED;
|
||||
if (xs->flags&SCSI_NOMASK)
|
||||
r = COMPLETE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
/*
|
||||
do {
|
||||
if (ncr5380_poll(xs->sc_link->scsibus, xs->timeout)) {
|
||||
if ( ! ( xs->flags & SCSI_SILENT ) )
|
||||
printf("cmd fail.\n");
|
||||
cmd_cleanup
|
||||
xs->error = XS_DRIVER_STUFFUP;
|
||||
splx(s);
|
||||
}
|
||||
} while ( ! ( xs->flags & ITSDONE ) );
|
||||
*/
|
||||
}
|
||||
|
||||
static int
|
||||
ncr5380_show_scsi_cmd(struct scsi_xfer *xs)
|
||||
{
|
||||
u_char *b = (u_char *) xs->cmd;
|
||||
int i = 0;
|
||||
|
||||
if ( ! ( xs->flags & SCSI_RESET ) ) {
|
||||
printf("si(%d:%d:%d)-",
|
||||
xs->sc_link->scsibus, xs->sc_link->target, xs->sc_link->lun);
|
||||
while (i < xs->cmdlen) {
|
||||
if (i) printf(",");
|
||||
printf("%x",b[i++]);
|
||||
}
|
||||
printf("-\n");
|
||||
} else {
|
||||
printf("si(%d:%d:%d)-RESET-\n",
|
||||
xs->sc_link->scsibus, xs->sc_link->target, xs->sc_link->lun);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Actual chip control.
|
||||
*/
|
||||
|
||||
static void
|
||||
delay(int timeo)
|
||||
{
|
||||
int len;
|
||||
for (len=0;len<timeo*2;len++);
|
||||
}
|
||||
|
||||
extern void
|
||||
spinwait(int ms)
|
||||
{
|
||||
while (ms--)
|
||||
delay(500);
|
||||
}
|
||||
|
||||
extern void
|
||||
ncr5380_intr(int adapter)
|
||||
{
|
||||
register struct ncr5380_softc *ncr5380 = ncrcd.cd_devs[adapter];
|
||||
register volatile sci_regmap_t *regs = ncr5380->sc_regs;
|
||||
|
||||
SCI_CLR_INTR(regs);
|
||||
regs->sci_mode = 0x00;
|
||||
}
|
||||
|
||||
#if 0
|
||||
extern int
|
||||
scsi_irq_intr(void)
|
||||
{
|
||||
register volatile sci_regmap_t *regs = ncr;
|
||||
|
||||
/* if (regs->sci_csr != SCI_CSR_PHASE_MATCH)
|
||||
printf("scsi_irq_intr called (not just phase match -- "
|
||||
"csr = 0x%x, bus_csr = 0x%x).\n",
|
||||
regs->sci_csr, regs->sci_bus_csr);
|
||||
ncr5380_intr(0); */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
extern int
|
||||
scsi_drq_intr(void)
|
||||
{
|
||||
/* printf("scsi_drq_intr called.\n"); */
|
||||
/* ncr5380_intr(0); */
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ncr5380_reset_target(int adapter, int target)
|
||||
{
|
||||
register struct ncr5380_softc *ncr5380 = ncrcd.cd_devs[adapter];
|
||||
register volatile sci_regmap_t *regs = ncr5380->sc_regs;
|
||||
int dummy;
|
||||
|
||||
regs->sci_icmd = SCI_ICMD_TEST;
|
||||
regs->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST;
|
||||
delay(2500);
|
||||
regs->sci_icmd = 0;
|
||||
|
||||
regs->sci_mode = 0;
|
||||
regs->sci_tcmd = SCI_PHASE_DISC;
|
||||
regs->sci_sel_enb = 0;
|
||||
|
||||
SCI_CLR_INTR(regs);
|
||||
SCI_CLR_INTR(regs);
|
||||
}
|
||||
|
||||
static int
|
||||
ncr5380_poll(int adapter, int timeout)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
ncr5380_send_cmd(struct scsi_xfer *xs)
|
||||
{
|
||||
int s;
|
||||
int sense;
|
||||
|
||||
/* ncr5380_show_scsi_cmd(xs); */
|
||||
s = splbio();
|
||||
sense = scsi_gen( xs->sc_link->scsibus, xs->sc_link->target,
|
||||
xs->sc_link->lun, xs->cmd, xs->cmdlen,
|
||||
xs->data, xs->datalen );
|
||||
splx(s);
|
||||
if (sense) {
|
||||
switch (sense) {
|
||||
case 0x02: /* Check condition */
|
||||
/* printf("check cond. target %d.\n", xs->targ);*/
|
||||
s = splbio();
|
||||
scsi_group0(xs->sc_link->scsibus,
|
||||
xs->sc_link->target,
|
||||
xs->sc_link->lun,
|
||||
0x3, 0x0,
|
||||
sizeof(struct scsi_sense_data),
|
||||
0, (caddr_t) &(xs->sense),
|
||||
sizeof(struct scsi_sense_data));
|
||||
splx(s);
|
||||
xs->error = XS_SENSE;
|
||||
return HAD_ERROR;
|
||||
case 0x08: /* Busy */
|
||||
xs->error = XS_BUSY;
|
||||
return HAD_ERROR;
|
||||
default:
|
||||
xs->error = XS_DRIVER_STUFFUP;
|
||||
return HAD_ERROR;
|
||||
}
|
||||
}
|
||||
xs->error = XS_NOERROR;
|
||||
return (COMPLETE);
|
||||
}
|
||||
|
||||
static int
|
||||
select_target(register volatile sci_regmap_t *regs,
|
||||
u_char myid, u_char tid, int with_atn)
|
||||
{
|
||||
register u_char bid, icmd;
|
||||
int ret = SCSI_RET_RETRY;
|
||||
|
||||
if ((regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
|
||||
(regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
|
||||
(regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)))
|
||||
return ret;
|
||||
|
||||
/* for our purposes.. */
|
||||
myid = 1 << myid;
|
||||
tid = 1 << tid;
|
||||
|
||||
regs->sci_sel_enb = 0; /*myid; we don't want any interrupts. */
|
||||
|
||||
regs->sci_odata = myid;
|
||||
regs->sci_mode = SCI_MODE_ARB;
|
||||
/* regs->sci_mode |= SCI_MODE_ARB; */
|
||||
/* AIP might not set if BSY went true after we checked */
|
||||
for (bid = 0; bid < 20; bid++) /* 20usec circa */
|
||||
if (regs->sci_icmd & SCI_ICMD_AIP)
|
||||
break;
|
||||
if ((regs->sci_icmd & SCI_ICMD_AIP) == 0) {
|
||||
goto lost;
|
||||
}
|
||||
|
||||
spinwait(2); /* 2.2us arb delay */
|
||||
|
||||
if (regs->sci_icmd & SCI_ICMD_LST) {
|
||||
goto lost;
|
||||
}
|
||||
|
||||
regs->sci_mode &= ~SCI_MODE_PAR_CHK;
|
||||
bid = regs->sci_data;
|
||||
|
||||
if ((bid & ~myid) > myid) {
|
||||
goto lost;
|
||||
}
|
||||
if (regs->sci_icmd & SCI_ICMD_LST) {
|
||||
goto lost;
|
||||
}
|
||||
|
||||
/* Won arbitration, enter selection phase now */
|
||||
icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
|
||||
icmd |= (with_atn ? (SCI_ICMD_SEL|SCI_ICMD_ATN) : SCI_ICMD_SEL);
|
||||
icmd |= SCI_ICMD_BSY;
|
||||
regs->sci_icmd = icmd;
|
||||
|
||||
if (regs->sci_icmd & SCI_ICMD_LST) {
|
||||
goto nosel;
|
||||
}
|
||||
|
||||
/* XXX a target that violates specs might still drive the bus XXX */
|
||||
/* XXX should put our id out, and after the delay check nothi XXX */
|
||||
/* XXX ng else is out there. XXX */
|
||||
|
||||
delay(0);
|
||||
|
||||
regs->sci_tcmd = 0;
|
||||
regs->sci_odata = myid | tid;
|
||||
regs->sci_sel_enb = 0;
|
||||
|
||||
/* regs->sci_mode &= ~SCI_MODE_ARB; 2 deskew delays, too */
|
||||
regs->sci_mode = 0; /* 2 deskew delays, too */
|
||||
|
||||
icmd |= SCI_ICMD_DATA;
|
||||
icmd &= ~(SCI_ICMD_BSY);
|
||||
|
||||
regs->sci_icmd = icmd;
|
||||
|
||||
/* bus settle delay, 400ns */
|
||||
delay(2); /* too much (was 2) ? */
|
||||
|
||||
/* regs->sci_mode |= SCI_MODE_PAR_CHK; */
|
||||
|
||||
{
|
||||
register int timeo = 2500;/* 250 msecs in 100 usecs chunks */
|
||||
while ((regs->sci_bus_csr & SCI_BUS_BSY) == 0) {
|
||||
if (--timeo > 0) {
|
||||
delay(100);
|
||||
} else {
|
||||
goto nodev;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL);
|
||||
regs->sci_icmd = icmd;
|
||||
/* regs->sci_sel_enb = myid;*/ /* looks like we should NOT have it */
|
||||
return SCSI_RET_SUCCESS;
|
||||
nodev:
|
||||
ret = SCSI_RET_DEVICE_DOWN;
|
||||
regs->sci_sel_enb = myid;
|
||||
nosel:
|
||||
icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL|SCI_ICMD_ATN);
|
||||
regs->sci_icmd = icmd;
|
||||
lost:
|
||||
regs->sci_mode = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
sci_data_out(regs, phase, count, data)
|
||||
register sci_regmap_t *regs;
|
||||
unsigned char *data;
|
||||
{
|
||||
register unsigned char icmd;
|
||||
register int cnt=0;
|
||||
|
||||
/* ..checks.. */
|
||||
|
||||
icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
|
||||
loop:
|
||||
if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
|
||||
return cnt;
|
||||
|
||||
WAIT_FOR_REQ(regs);
|
||||
icmd |= SCI_ICMD_DATA;
|
||||
regs->sci_icmd = icmd;
|
||||
regs->sci_odata = *data++;
|
||||
icmd |= SCI_ICMD_ACK;
|
||||
regs->sci_icmd = icmd;
|
||||
|
||||
icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_ACK);
|
||||
WAIT_FOR_NOT_REQ(regs);
|
||||
regs->sci_icmd = icmd;
|
||||
++cnt;
|
||||
if (--count > 0)
|
||||
goto loop;
|
||||
scsi_timeout_error:
|
||||
return cnt;
|
||||
}
|
||||
|
||||
sci_data_in(regs, phase, count, data)
|
||||
register sci_regmap_t *regs;
|
||||
unsigned char *data;
|
||||
{
|
||||
register unsigned char icmd;
|
||||
register int cnt=0;
|
||||
|
||||
/* ..checks.. */
|
||||
|
||||
icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
|
||||
|
||||
loop:
|
||||
if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
|
||||
return cnt;
|
||||
|
||||
WAIT_FOR_REQ(regs);
|
||||
*data++ = regs->sci_data;
|
||||
icmd |= SCI_ICMD_ACK;
|
||||
regs->sci_icmd = icmd;
|
||||
|
||||
icmd &= ~SCI_ICMD_ACK;
|
||||
WAIT_FOR_NOT_REQ(regs);
|
||||
regs->sci_icmd = icmd;
|
||||
++cnt;
|
||||
if (--count > 0)
|
||||
goto loop;
|
||||
|
||||
scsi_timeout_error:
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static int
|
||||
command_transfer(register volatile sci_regmap_t *regs,
|
||||
int maxlen, u_char *data, u_char *status, u_char *msg)
|
||||
{
|
||||
int xfer=0, phase;
|
||||
|
||||
/* printf("command_transfer called for 0x%x.\n", *data); */
|
||||
|
||||
regs->sci_icmd = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
WAIT_FOR_REQ(regs);
|
||||
|
||||
phase = SCI_CUR_PHASE(regs->sci_bus_csr);
|
||||
|
||||
switch (phase) {
|
||||
case SCSI_PHASE_CMD:
|
||||
SCI_ACK(regs,SCSI_PHASE_CMD);
|
||||
xfer += sci_data_out(regs, SCSI_PHASE_CMD,
|
||||
maxlen, data);
|
||||
return xfer;
|
||||
case SCSI_PHASE_DATA_IN:
|
||||
printf("Data in phase in command_transfer?\n");
|
||||
return 0;
|
||||
case SCSI_PHASE_DATA_OUT:
|
||||
printf("Data out phase in command_transfer?\n");
|
||||
return 0;
|
||||
case SCSI_PHASE_STATUS:
|
||||
SCI_ACK(regs,SCSI_PHASE_STATUS);
|
||||
printf("status in command_transfer.\n");
|
||||
sci_data_in(regs, SCSI_PHASE_STATUS,
|
||||
1, status);
|
||||
break;
|
||||
case SCSI_PHASE_MESSAGE_IN:
|
||||
SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
|
||||
printf("msgin in command_transfer.\n");
|
||||
sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
|
||||
1, msg);
|
||||
break;
|
||||
case SCSI_PHASE_MESSAGE_OUT:
|
||||
SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
|
||||
sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
|
||||
1, msg);
|
||||
break;
|
||||
default:
|
||||
printf("Unexpected phase 0x%x in "
|
||||
"command_transfer().\n", phase);
|
||||
scsi_timeout_error:
|
||||
return xfer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
data_transfer(register volatile sci_regmap_t *regs,
|
||||
int maxlen, u_char *data, u_char *status, u_char *msg)
|
||||
{
|
||||
int retlen = 0, xfer, phase;
|
||||
|
||||
regs->sci_icmd = 0;
|
||||
|
||||
*status = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
WAIT_FOR_REQ(regs);
|
||||
|
||||
phase = SCI_CUR_PHASE(regs->sci_bus_csr);
|
||||
|
||||
switch (phase) {
|
||||
case SCSI_PHASE_CMD:
|
||||
printf("Command phase in data_transfer().\n");
|
||||
return retlen;
|
||||
case SCSI_PHASE_DATA_IN:
|
||||
SCI_ACK(regs,SCSI_PHASE_DATA_IN);
|
||||
#if PSEUDO_DMA
|
||||
xfer = sci_pdma_in(regs, SCSI_PHASE_DATA_IN,
|
||||
maxlen, data);
|
||||
#else
|
||||
xfer = sci_data_in(regs, SCSI_PHASE_DATA_IN,
|
||||
maxlen, data);
|
||||
#endif
|
||||
retlen += xfer;
|
||||
maxlen -= xfer;
|
||||
break;
|
||||
case SCSI_PHASE_DATA_OUT:
|
||||
SCI_ACK(regs,SCSI_PHASE_DATA_OUT);
|
||||
#if PSEUDO_DMA
|
||||
xfer = sci_pdma_out(regs, SCSI_PHASE_DATA_OUT,
|
||||
maxlen, data);
|
||||
#else
|
||||
xfer = sci_data_out(regs, SCSI_PHASE_DATA_OUT,
|
||||
maxlen, data);
|
||||
#endif
|
||||
retlen += xfer;
|
||||
maxlen -= xfer;
|
||||
break;
|
||||
case SCSI_PHASE_STATUS:
|
||||
SCI_ACK(regs,SCSI_PHASE_STATUS);
|
||||
sci_data_in(regs, SCSI_PHASE_STATUS,
|
||||
1, status);
|
||||
break;
|
||||
case SCSI_PHASE_MESSAGE_IN:
|
||||
SCI_ACK(regs,SCSI_PHASE_MESSAGE_IN);
|
||||
sci_data_in(regs, SCSI_PHASE_MESSAGE_IN,
|
||||
1, msg);
|
||||
if (*msg == 0) {
|
||||
return retlen;
|
||||
} else {
|
||||
printf( "message 0x%x in "
|
||||
"data_transfer.\n", *msg);
|
||||
}
|
||||
break;
|
||||
case SCSI_PHASE_MESSAGE_OUT:
|
||||
SCI_ACK(regs,SCSI_PHASE_MESSAGE_OUT);
|
||||
sci_data_out(regs, SCSI_PHASE_MESSAGE_OUT,
|
||||
1, msg);
|
||||
break;
|
||||
default:
|
||||
printf( "Unexpected phase 0x%x in "
|
||||
"data_transfer().\n", phase);
|
||||
scsi_timeout_error:
|
||||
return retlen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
scsi_request(register volatile sci_regmap_t *regs,
|
||||
int target, int lun, u_char *cmd, int cmdlen,
|
||||
char *databuf, int datalen, int *sent, int *ret)
|
||||
{
|
||||
/* Returns 0 on success, -1 on internal error, or the status byte */
|
||||
int cmd_bytes_sent, r;
|
||||
u_char stat, msg, c;
|
||||
|
||||
*sent = 0;
|
||||
|
||||
if ( ( r = select_target(regs, 7, target, 1) ) != SCSI_RET_SUCCESS) {
|
||||
*ret = r;
|
||||
SCI_CLR_INTR(regs);
|
||||
switch (r) {
|
||||
case SCSI_RET_RETRY:
|
||||
return 0x08;
|
||||
default:
|
||||
printf("select_target(target %d, lun %d) failed(%d).\n",
|
||||
target, lun, r);
|
||||
case SCSI_RET_DEVICE_DOWN:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
c = 0x80 | lun;
|
||||
|
||||
if ((cmd_bytes_sent = command_transfer(regs, cmdlen,
|
||||
(u_char *) cmd, &stat, &c))
|
||||
!= cmdlen) {
|
||||
SCI_CLR_INTR(regs);
|
||||
*ret = SCSI_RET_COMMAND_FAIL;
|
||||
printf("Data underrun sending CCB (%d bytes of %d, sent).\n",
|
||||
cmd_bytes_sent, cmdlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*sent=data_transfer(regs, datalen, (u_char *)databuf,
|
||||
&stat, &msg);
|
||||
|
||||
*ret = 0;
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int
|
||||
scsi_gen(int adapter, int id, int lun, struct scsi_generic *cmd,
|
||||
int cmdlen, void *databuf, int datalen)
|
||||
{
|
||||
register struct ncr5380_softc *ncr5380 = ncrcd.cd_devs[adapter];
|
||||
register volatile sci_regmap_t *regs = ncr5380->sc_regs;
|
||||
int i,j,sent,ret;
|
||||
|
||||
cmd->bytes[0] = ((u_char) lun << 5);
|
||||
|
||||
i = scsi_request(regs, id, lun, (u_char *) cmd, cmdlen,
|
||||
databuf, datalen, &sent, &ret);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
scsi_group0(int adapter, int id, int lun, int opcode, int addr, int len,
|
||||
int flags, caddr_t databuf, int datalen)
|
||||
{
|
||||
register struct ncr5380_softc *ncr5380 = ncrcd.cd_devs[adapter];
|
||||
register volatile sci_regmap_t *regs = ncr5380->sc_regs;
|
||||
unsigned char cmd[6];
|
||||
int i,j,sent,ret;
|
||||
|
||||
cmd[0] = opcode; /* Operation code */
|
||||
cmd[1] = (lun << 5) | ((addr >> 16) & 0x1F); /* Lun & MSB of addr */
|
||||
cmd[2] = (addr >> 8) & 0xFF; /* addr */
|
||||
cmd[3] = addr & 0xFF; /* LSB of addr */
|
||||
cmd[4] = len; /* Allocation length */
|
||||
cmd[5] = flags; /* Link/Flag */
|
||||
|
||||
i = scsi_request(regs, id, lun, cmd, 6, databuf, datalen, &sent, &ret);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* pseudo-dma action */
|
||||
|
||||
#if PSEUDO_DMA
|
||||
|
||||
#define TIMEOUT 1000000
|
||||
#define READY(poll) \
|
||||
i = TIMEOUT; \
|
||||
while ((regs->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) \
|
||||
!=(SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH)) \
|
||||
if ( !(regs->sci_csr & SCI_CSR_PHASE_MATCH) \
|
||||
|| !(regs->sci_bus_csr & SCI_BUS_BSY) \
|
||||
|| (i-- < 0) ) { \
|
||||
printf("scsi.c: timeout counter = %d, len = %d count=%d (count-len %d).\n", \
|
||||
i, len,count,count-len); \
|
||||
printf("pdebug = %d, 1=out, 2=in",pdebug); \
|
||||
/*dump_regs();*/ \
|
||||
if (poll && !(regs->sci_csr & SCI_CSR_PHASE_MATCH)) { \
|
||||
regs->sci_icmd &= ~SCI_ICMD_DATA; \
|
||||
len--; \
|
||||
} else { \
|
||||
regs->sci_mode &= ~SCI_MODE_DMA; \
|
||||
} \
|
||||
return count-len; \
|
||||
}
|
||||
|
||||
#define W1 *byte_data = *data++
|
||||
#define W4 W1; W1; W1; W1;
|
||||
/*#define W4 *long_data = *((long*)data)++*/
|
||||
|
||||
sci_pdma_out(regs, phase, count, data)
|
||||
register volatile sci_regmap_t *regs;
|
||||
int phase;
|
||||
int count;
|
||||
u_char *data;
|
||||
{
|
||||
register volatile u_char *byte_data = (u_char *)®s->sci_data;
|
||||
register int len = count, i;
|
||||
|
||||
pdebug=1;
|
||||
|
||||
if (count < 128)
|
||||
return sci_data_out(regs, phase, count, data);
|
||||
|
||||
WAIT_FOR_BSY(regs);
|
||||
regs->sci_mode |= SCI_MODE_DMA;
|
||||
regs->sci_icmd |= SCI_ICMD_DATA;
|
||||
regs->sci_dma_send = 0;
|
||||
|
||||
while ( len >= 64 ) {
|
||||
READY(1); W1; READY(1); W1; READY(1); W1; READY(1); W1;
|
||||
READY(1);
|
||||
W4;W4;W4; W4;W4;W4;W4; W4;W4;W4;W4; W4;W4;W4;W4;
|
||||
len -= 64;
|
||||
}
|
||||
while (len) {
|
||||
READY(1);
|
||||
W1;
|
||||
len--;
|
||||
}
|
||||
i = TIMEOUT;
|
||||
while ( ((regs->sci_csr & (SCI_CSR_DREQ|SCI_CSR_PHASE_MATCH))
|
||||
== SCI_CSR_PHASE_MATCH) && --i);
|
||||
if (!i)
|
||||
printf("scsi.c:%d: timeout waiting for SCI_CSR_DREQ.\n", __LINE__);
|
||||
*byte_data = 0;
|
||||
scsi_timeout_error:
|
||||
regs->sci_mode &= ~SCI_MODE_DMA;
|
||||
return count-len;
|
||||
}
|
||||
|
||||
#undef W1
|
||||
#undef W4
|
||||
|
||||
|
||||
#define R1 *data++ = *byte_data
|
||||
#define R4 R1; R1; R1; R1;
|
||||
/*#define R4 (*((long *)data)++ = *long_data*/
|
||||
sci_pdma_in(regs, phase, count, data)
|
||||
register volatile sci_regmap_t *regs;
|
||||
int phase;
|
||||
int count;
|
||||
u_char *data;
|
||||
{
|
||||
register volatile u_char *byte_data = (u_char *) ®s->sci_data;
|
||||
register int len = count, i;
|
||||
|
||||
pdebug=2;
|
||||
if (count < 128)
|
||||
return sci_data_in(regs, phase, count, data);
|
||||
|
||||
/* printf("Called sci_pdma_in(0x%x, 0x%x, %d, 0x%x.\n", regs, phase, count, data); */
|
||||
|
||||
WAIT_FOR_BSY(regs);
|
||||
regs->sci_mode |= SCI_MODE_DMA;
|
||||
regs->sci_icmd |= SCI_ICMD_DATA;
|
||||
regs->sci_irecv = 0;
|
||||
|
||||
while (len >= 1024) {
|
||||
READY(0);
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 128 */
|
||||
READY(0);
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 256 */
|
||||
READY(0);
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 384 */
|
||||
READY(0);
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 512 */
|
||||
READY(0);
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 640 */
|
||||
READY(0);
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 768 */
|
||||
READY(0);
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 896 */
|
||||
READY(0);
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /*1024 */
|
||||
len -= 1024;
|
||||
}
|
||||
while (len >= 128) {
|
||||
READY(0);
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4;
|
||||
R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; R4;R4;R4;R4; /* 128 */
|
||||
len -= 128;
|
||||
}
|
||||
while (len) {
|
||||
READY(0);
|
||||
R1;
|
||||
len--;
|
||||
}
|
||||
scsi_timeout_error:
|
||||
regs->sci_mode &= ~SCI_MODE_DMA;
|
||||
return count - len;
|
||||
}
|
||||
#undef R4
|
||||
#undef R1
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* @(#)vuid_event.h 8.1 (Berkeley) 6/11/93
|
||||
*
|
||||
* from: Header: vuid_event.h,v 1.4 92/11/26 01:20:27 torek Exp (LBL)
|
||||
* $Id: vuid_event.h,v 1.1 1994/02/23 08:28:58 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following is a minimal emulation of Sun's `Firm_event' structures
|
||||
* and related operations necessary to make X11 happy (i.e., make it
|
||||
* compile, and make old X11 binaries run).
|
||||
*/
|
||||
typedef struct firm_event {
|
||||
u_short id; /* key or MS_* or LOC_[XY]_DELTA */
|
||||
u_short pad; /* unused, at least by X11 */
|
||||
int value; /* VKEY_{UP,DOWN} or locator delta */
|
||||
struct timeval time;
|
||||
} Firm_event;
|
||||
|
||||
/*
|
||||
* Special `id' fields. These weird numbers simply match the old binaries.
|
||||
* Others are in 0..0x7f and are keyboard key numbers (keyboard dependent!).
|
||||
*/
|
||||
#define MS_LEFT 0x7f20 /* left mouse button */
|
||||
#define MS_MIDDLE 0x7f21 /* middle mouse button */
|
||||
#define MS_RIGHT 0x7f22 /* right mouse button */
|
||||
#define LOC_X_DELTA 0x7f80 /* mouse delta-X */
|
||||
#define LOC_Y_DELTA 0x7f81 /* mouse delta-Y */
|
||||
|
||||
/*
|
||||
* Special `value' fields. These apply to keys and mouse buttons. The
|
||||
* value of a mouse delta is the delta. Note that positive deltas are
|
||||
* left and up (not left and down as you might expect).
|
||||
*/
|
||||
#define VKEY_UP 0 /* key or button went up */
|
||||
#define VKEY_DOWN 1 /* key or button went down */
|
||||
|
||||
/*
|
||||
* The following ioctls are clearly intended to take things in and out
|
||||
* of `firm event' mode. Since we always run in this mode (as far as
|
||||
* /dev/kbd and /dev/mouse are concerned, anyway), we always claim to
|
||||
* be in this mode and reject anything else.
|
||||
*/
|
||||
#define VUIDSFORMAT _IOW('v', 1, int)
|
||||
#define VUIDGFORMAT _IOR('v', 2, int)
|
||||
#define VUID_FIRM_EVENT 1 /* the only format we support */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,433 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* @(#)zsreg.h 8.1 (Berkeley) 6/11/93
|
||||
*
|
||||
* from: Header: zsreg.h,v 1.7 92/11/26 01:27:18 torek Exp (LBL)
|
||||
* $Id: zsreg.h,v 1.1 1994/02/23 08:29:03 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Zilog SCC registers, as implemented on the Sun-4c.
|
||||
*
|
||||
* Each Z8530 implements two channels (called `a' and `b').
|
||||
*
|
||||
* The damnable chip was designed to fit on Z80 I/O ports, and thus
|
||||
* has everything multiplexed out the wazoo. We have to select
|
||||
* a register, then read or write the register, and so on. Worse,
|
||||
* the parameter bits are scattered all over the register space.
|
||||
* This thing is full of `miscellaneous' control registers.
|
||||
*
|
||||
* Worse yet, the registers have incompatible functions on read
|
||||
* and write operations. We describe the registers below according
|
||||
* to whether they are `read registers' (RR) or `write registers' (WR).
|
||||
* As if this were not enough, some of the channel B status bits show
|
||||
* up in channel A, and vice versa. The blasted thing shares write
|
||||
* registers 2 and 9 across both channels, and reads registers 2 and 3
|
||||
* differently for the two channels. We can, however, ignore this much
|
||||
* of the time.
|
||||
*/
|
||||
#ifndef LOCORE
|
||||
struct zschan {
|
||||
u_char zc_csr; /* control and status, and indirect access */
|
||||
u_char zc_xxx0;
|
||||
u_char zc_data; /* data */
|
||||
u_char zc_xxx1;
|
||||
};
|
||||
|
||||
/*
|
||||
* N.B.: the keyboard is channel 1, the mouse channel 0; ttyb is 1, ttya
|
||||
* is 0. In other words, the things are BACKWARDS.
|
||||
*/
|
||||
struct zsdevice {
|
||||
struct zschan zs_chan[2]; /* channel A = 1, B = 0 */
|
||||
};
|
||||
|
||||
#define CHAN_A 1
|
||||
#define CHAN_B 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some of the names in this files were chosen to make the hsis driver
|
||||
* work unchanged (which means that they will match some in SunOS).
|
||||
*
|
||||
* `S.C.' stands for Special Condition, which is any of these:
|
||||
* receiver overrun (aka silo overflow)
|
||||
* framing error (missing stop bit, etc)
|
||||
* end of frame (in synchronous modes)
|
||||
* parity error (when `parity error is S.C.' is set)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Registers with only a single `numeric value' get a name.
|
||||
* Other registers hold bits and are only numbered; the bit
|
||||
* definitions imply the register number (see below).
|
||||
*
|
||||
* We never use the receive and transmit data registers as
|
||||
* indirects (choosing instead the zc_data register), so they
|
||||
* are not defined here.
|
||||
*/
|
||||
#define ZSRR_IVEC 2 /* interrupt vector (channel 0) */
|
||||
#define ZSRR_IPEND 3 /* interrupt pending (ch. 0 only) */
|
||||
#define ZSRR_BAUDLO 12 /* baud rate generator (low half) */
|
||||
#define ZSRR_BAUDHI 13 /* baud rate generator (high half) */
|
||||
|
||||
#define ZSWR_IVEC 2 /* interrupt vector (shared) */
|
||||
#define ZSWR_TXSYNC 6 /* sync transmit char (monosync mode) */
|
||||
#define ZSWR_RXSYNC 7 /* sync receive char (monosync mode) */
|
||||
#define ZSWR_SYNCLO 6 /* sync low byte (bisync mode) */
|
||||
#define ZSWR_SYNCHI 7 /* sync high byte (bisync mode) */
|
||||
#define ZSWR_SDLC_ADDR 6 /* SDLC address (SDLC mode) */
|
||||
#define ZSWR_SDLC_FLAG 7 /* SDLC flag 0x7E (SDLC mode) */
|
||||
#define ZSWR_BAUDLO 12 /* baud rate generator (low half) */
|
||||
#define ZSWR_BAUDHI 13 /* baud rate generator (high half) */
|
||||
|
||||
/*
|
||||
* Registers 0 through 7 may be written with any one of the 8 command
|
||||
* modifiers, and/or any one of the 4 reset modifiers, defined below.
|
||||
* To write registers 8 through 15, however, the command modifier must
|
||||
* always be `point high'. Rather than track this bizzareness all over
|
||||
* the driver, we try to avoid using any modifiers, ever (but they are
|
||||
* defined here if you want them).
|
||||
*/
|
||||
#define ZSM_RESET_TXUEOM 0xc0 /* reset xmit underrun / eom latch */
|
||||
#define ZSM_RESET_TXCRC 0x80 /* reset xmit crc generator */
|
||||
#define ZSM_RESET_RXCRC 0x40 /* reset recv crc checker */
|
||||
#define ZSM_NULL 0x00 /* nothing special */
|
||||
|
||||
#define ZSM_RESET_IUS 0x38 /* reset interrupt under service */
|
||||
#define ZSM_RESET_ERR 0x30 /* reset error cond */
|
||||
#define ZSM_RESET_TXINT 0x28 /* reset xmit interrupt pending */
|
||||
#define ZSM_EI_NEXTRXC 0x20 /* enable int. on next rcvd char */
|
||||
#define ZSM_SEND_ABORT 0x18 /* send abort (SDLC) */
|
||||
#define ZSM_RESET_STINT 0x10 /* reset external/status interrupt */
|
||||
#define ZSM_POINTHIGH 0x08 /* `point high' (use r8-r15) */
|
||||
#define ZSM_NULL 0x00 /* nothing special */
|
||||
|
||||
/*
|
||||
* Commands for Write Register 0 (`Command Register').
|
||||
* These are just the command modifiers or'ed with register number 0
|
||||
* (which of course equals the command modifier).
|
||||
*/
|
||||
#define ZSWR0_RESET_EOM ZSM_RESET_TXUEOM
|
||||
#define ZSWR0_RESET_TXCRC ZSM_RESET_TXCRC
|
||||
#define ZSWR0_RESET_RXCRC ZSM_RESET_RXCRC
|
||||
#define ZSWR0_CLR_INTR ZSM_RESET_IUS
|
||||
#define ZSWR0_RESET_ERRORS ZSM_RESET_ERR
|
||||
#define ZSWR0_EI_NEXTRXC ZSM_EI_NEXTRXC
|
||||
#define ZSWR0_SEND_ABORT ZSM_SEND_ABORT
|
||||
#define ZSWR0_RESET_STATUS ZSM_RESET_STINT
|
||||
#define ZSWR0_RESET_TXINT ZSM_RESET_TXINT
|
||||
|
||||
/*
|
||||
* Bits in Write Register 1 (`Transmit/Receive Interrupt and Data
|
||||
* Transfer Mode Definition'). Note that bits 3 and 4 are taken together
|
||||
* as a single unit, and bits 5 and 6 are useful only if bit 7 is set.
|
||||
*/
|
||||
#define ZSWR1_REQ_WAIT 0x80 /* WAIT*-REQ* pin gives WAIT* */
|
||||
#define ZSWR1_REQ_REQ 0xc0 /* WAIT*-REQ* pin gives REQ* */
|
||||
#define ZSWR1_REQ_TX 0x00 /* WAIT*-REQ* pin follows xmit buf */
|
||||
#define ZSWR1_REQ_RX 0x20 /* WAIT*-REQ* pin follows recv buf */
|
||||
|
||||
#define ZSWR1_RIE_NONE 0x00 /* disable rxint entirely */
|
||||
#define ZSWR1_RIE_FIRST 0x08 /* rxint on first char & on S.C. */
|
||||
#define ZSWR1_RIE 0x10 /* rxint per char & on S.C. */
|
||||
#define ZSWR1_RIE_SPECIAL_ONLY 0x18 /* rxint on S.C. only */
|
||||
|
||||
#define ZSWR1_PE_SC 0x04 /* parity error is special condition */
|
||||
#define ZSWR1_TIE 0x02 /* transmit interrupt enable */
|
||||
#define ZSWR1_SIE 0x01 /* external/status interrupt enable */
|
||||
|
||||
/* HSIS compat */
|
||||
#define ZSWR1_REQ_ENABLE (ZSWR1_REQ_WAIT | ZSWR1_REQ_TX)
|
||||
|
||||
/*
|
||||
* Bits in Write Register 3 (`Receive Parameters and Control').
|
||||
* Bits 7 and 6 are taken as a unit. Note that the receive bits
|
||||
* per character ordering is insane.
|
||||
*
|
||||
* Here `hardware flow control' means CTS enables the transmitter
|
||||
* and DCD enables the receiver. The latter is neither interesting
|
||||
* nor useful, and gets in our way, making it almost unusable.
|
||||
*/
|
||||
#define ZSWR3_RX_5 0x00 /* receive 5 bits per char */
|
||||
#define ZSWR3_RX_7 0x40 /* receive 7 bits per char */
|
||||
#define ZSWR3_RX_6 0x80 /* receive 6 bits per char */
|
||||
#define ZSWR3_RX_8 0xc0 /* receive 8 bits per char */
|
||||
|
||||
#define ZSWR3_HFC 0x20 /* hardware flow control */
|
||||
#define ZSWR3_HUNT 0x10 /* enter hunt mode */
|
||||
#define ZSWR3_RXCRC_ENABLE 0x08 /* enable recv crc calculation */
|
||||
#define ZSWR3_ADDR_SEARCH_MODE 0x04 /* address search mode (SDLC only) */
|
||||
#define ZSWR3_SYNC_LOAD_INH 0x02 /* sync character load inhibit */
|
||||
#define ZSWR3_RX_ENABLE 0x01 /* receiver enable */
|
||||
|
||||
/*
|
||||
* Bits in Write Register 4 (`Transmit/Receive Miscellaneous Parameters
|
||||
* and Modes'). Bits 7&6, 5&4, and 3&2 are taken as units.
|
||||
*/
|
||||
#define ZSWR4_CLK_X1 0x00 /* clock divisor = 1 */
|
||||
#define ZSWR4_CLK_X16 0x40 /* clock divisor = 16 */
|
||||
#define ZSWR4_CLK_X32 0x80 /* clock divisor = 32 */
|
||||
#define ZSWR4_CLK_X64 0xc0 /* clock divisor = 64 */
|
||||
|
||||
#define ZSWR4_MONOSYNC 0x00 /* 8 bit sync char (sync only) */
|
||||
#define ZSWR4_BISYNC 0x10 /* 16 bit sync char (sync only) */
|
||||
#define ZSWR4_SDLC 0x20 /* SDLC mode */
|
||||
#define ZSWR4_EXTSYNC 0x30 /* external sync mode */
|
||||
|
||||
#define ZSWR4_SYNCMODE 0x00 /* one of the above sync modes */
|
||||
#define ZSWR4_ONESB 0x04 /* 1 stop bit */
|
||||
#define ZSWR4_1P5SB 0x08 /* 1.5 stop bits (clk cannot be 1x) */
|
||||
#define ZSWR4_TWOSB 0x0c /* 2 stop bits */
|
||||
|
||||
#define ZSWR4_EVENP 0x02 /* check for even parity */
|
||||
#define ZSWR4_PARENB 0x01 /* enable parity checking */
|
||||
|
||||
/*
|
||||
* Bits in Write Register 5 (`Transmit Parameter and Controls').
|
||||
* Bits 6 and 5 are taken as a unit; the ordering is, as with RX
|
||||
* bits per char, not sensible.
|
||||
*/
|
||||
#define ZSWR5_DTR 0x80 /* assert (set to -12V) DTR */
|
||||
|
||||
#define ZSWR5_TX_5 0x00 /* transmit 5 or fewer bits */
|
||||
#define ZSWR5_TX_7 0x20 /* transmit 7 bits */
|
||||
#define ZSWR5_TX_6 0x40 /* transmit 6 bits */
|
||||
#define ZSWR5_TX_8 0x60 /* transmit 8 bits */
|
||||
|
||||
#define ZSWR5_BREAK 0x10 /* send break (continuous 0s) */
|
||||
#define ZSWR5_TX_ENABLE 0x08 /* enable transmitter */
|
||||
#define ZSWR5_CRC16 0x04 /* use CRC16 (off => use SDLC) */
|
||||
#define ZSWR5_RTS 0x02 /* assert RTS */
|
||||
#define ZSWR5_TXCRC_ENABLE 0x01 /* enable xmit crc calculation */
|
||||
|
||||
#ifdef not_done_here
|
||||
/*
|
||||
* Bits in Write Register 7 when the chip is in SDLC mode.
|
||||
*/
|
||||
#define ZSWR7_SDLCFLAG 0x7e /* this value makes SDLC mode work */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Bits in Write Register 9 (`Master Interrupt Control'). Bits 7 & 6
|
||||
* are taken as a unit and indicate the type of reset; 00 means no reset
|
||||
* (and is not defined here).
|
||||
*/
|
||||
#define ZSWR9_HARD_RESET 0xc0 /* force hardware reset */
|
||||
#define ZSWR9_A_RESET 0x80 /* reset channel A (0) */
|
||||
#define ZSWR9_B_RESET 0x40 /* reset channel B (1) */
|
||||
/* 0x20 unused */
|
||||
|
||||
#define ZSWR9_STATUS_HIGH 0x10 /* status in high bits of intr vec */
|
||||
#define ZSWR9_MASTER_IE 0x08 /* master interrupt enable */
|
||||
#define ZSWR9_DLC 0x04 /* disable lower chain */
|
||||
#define ZSWR9_NO_VECTOR 0x02 /* no vector */
|
||||
#define ZSWR9_VECTOR_INCL_STAT 0x01 /* vector includes status */
|
||||
|
||||
/*
|
||||
* Bits in Write Register 10 (`Miscellaneous Transmitter/Receiver Control
|
||||
* Bits'). Bits 6 & 5 are taken as a unit, and some of the bits are
|
||||
* meaningful only in certain modes. Bleah.
|
||||
*/
|
||||
#define ZSWR10_PRESET_ONES 0x80 /* preset CRC to all 1 (else all 0) */
|
||||
|
||||
#define ZSWR10_NRZ 0x00 /* NRZ encoding */
|
||||
#define ZSWR10_NRZI 0x20 /* NRZI encoding */
|
||||
#define ZSWR10_FM1 0x40 /* FM1 encoding */
|
||||
#define ZSWR10_FM0 0x60 /* FM0 encoding */
|
||||
|
||||
#define ZSWR10_GA_ON_POLL 0x10 /* go active on poll (loop mode) */
|
||||
#define ZSWR10_MARK_IDLE 0x08 /* all 1s (vs flag) when idle (SDLC) */
|
||||
#define ZSWR10_ABORT_ON_UNDERRUN 0x4 /* abort on xmit underrun (SDLC) */
|
||||
#define ZSWR10_LOOP_MODE 0x02 /* loop mode (SDLC) */
|
||||
#define ZSWR10_6_BIT_SYNC 0x01 /* 6 bits per sync char (sync modes) */
|
||||
|
||||
/*
|
||||
* Bits in Write Register 11 (`Clock Mode Control'). Bits 6&5, 4&3, and
|
||||
* 1&0 are taken as units. Various bits depend on other bits in complex
|
||||
* ways; see the Zilog manual.
|
||||
*/
|
||||
#define ZSWR11_XTAL 0x80 /* have xtal between RTxC* and SYNC* */
|
||||
/* (else have TTL oscil. on RTxC*) */
|
||||
#define ZSWR11_RXCLK_RTXC 0x00 /* recv clock taken from TRxC* pin */
|
||||
#define ZSWR11_RXCLK_TRXC 0x20 /* recv clock taken from TRxC* pin */
|
||||
#define ZSWR11_RXCLK_BAUD 0x40 /* recv clock taken from BRG */
|
||||
#define ZSWR11_RXCLK_DPLL 0x60 /* recv clock taken from DPLL */
|
||||
|
||||
#define ZSWR11_TXCLK_RTXC 0x00 /* xmit clock taken from TRxC* pin */
|
||||
#define ZSWR11_TXCLK_TRXC 0x08 /* xmit clock taken from RTxC* pin */
|
||||
#define ZSWR11_TXCLK_BAUD 0x10 /* xmit clock taken from BRG */
|
||||
#define ZSWR11_TXCLK_DPLL 0x18 /* xmit clock taken from DPLL */
|
||||
|
||||
#define ZSWR11_TRXC_OUT_ENA 0x04 /* TRxC* pin will be an output */
|
||||
/* (unless it is being used above) */
|
||||
#define ZSWR11_TRXC_XTAL 0x00 /* TRxC output from xtal oscillator */
|
||||
#define ZSWR11_TRXC_XMIT 0x01 /* TRxC output from xmit clock */
|
||||
#define ZSWR11_TRXC_BAUD 0x02 /* TRxC output from BRG */
|
||||
#define ZSWR11_TRXC_DPLL 0x03 /* TRxC output from DPLL */
|
||||
|
||||
/*
|
||||
* Formula for Write Registers 12 and 13 (`Lower Byte of Baud Rate
|
||||
* Generator Time Constant' and `Upper Byte of ...'). Inputs:
|
||||
*
|
||||
* f BRG input clock frequency (in Hz) AFTER division
|
||||
* by 1, 16, 32, or 64 (per clock divisor in WR4)
|
||||
* bps desired rate in bits per second (9600, etc)
|
||||
*
|
||||
* We want
|
||||
*
|
||||
* f
|
||||
* ----- + 0.5 - 2
|
||||
* 2 bps
|
||||
*
|
||||
* rounded down to an integer. This can be computed entirely
|
||||
* in integer arithemtic as:
|
||||
*
|
||||
* f + bps
|
||||
* ------- - 2
|
||||
* 2 bps
|
||||
*/
|
||||
#define BPS_TO_TCONST(f, bps) ((((f) + (bps)) / (2 * (bps))) - 2)
|
||||
|
||||
/* inverse of above: given a BRG Time Constant, return Bits Per Second */
|
||||
#define TCONST_TO_BPS(f, tc) ((f) / 2 / ((tc) + 2))
|
||||
|
||||
/*
|
||||
* Bits in Write Register 14 (`Miscellaneous Control Bits').
|
||||
* Bits 7 through 5 are taken as a unit and make up a `DPLL command'.
|
||||
*/
|
||||
#define ZSWR14_DPLL_NOOP 0x00 /* leave DPLL alone */
|
||||
#define ZSWR14_DPLL_SEARCH 0x20 /* enter search mode */
|
||||
#define ZSWR14_DPLL_RESET_CM 0x40 /* reset `clock missing' in RR10 */
|
||||
#define ZSWR14_DPLL_DISABLE 0x60 /* disable DPLL (continuous search) */
|
||||
#define ZSWR14_DPLL_SRC_BAUD 0x80 /* set DPLL src = BRG */
|
||||
#define ZSWR14_DPLL_SRC_RTXC 0xa0 /* set DPLL src = RTxC* or xtal osc */
|
||||
#define ZSWR14_DPLL_FM 0xc0 /* operate in FM mode */
|
||||
#define ZSWR14_DPLL_NRZI 0xe0 /* operate in NRZI mode */
|
||||
|
||||
#define ZSWR14_LOCAL_LOOPBACK 0x10 /* set local loopback mode */
|
||||
#define ZSWR14_AUTO_ECHO 0x08 /* set auto echo mode */
|
||||
#define ZSWR14_DTR_REQ 0x04 /* DTR*/REQ* pin gives REQ* */
|
||||
#define ZSWR14_BAUD_FROM_PCLK 0x02 /* BRG clock taken from PCLK */
|
||||
/* (else from RTxC* pin or xtal osc) */
|
||||
#define ZSWR14_BAUD_ENA 0x01 /* enable BRG countdown */
|
||||
|
||||
/*
|
||||
* Bits in Write Register 15 (`External/Status Interrupt Control').
|
||||
* Most of these cause status interrupts whenever the corresponding
|
||||
* bit or pin changes state (i.e., any rising or falling edge).
|
||||
*/
|
||||
#define ZSWR15_BREAK_IE 0x80 /* enable break/abort status int */
|
||||
#define ZSWR15_TXUEOM_IE 0x40 /* enable TX underrun/EOM status int */
|
||||
#define ZSWR15_CTS_IE 0x20 /* enable CTS* pin status int */
|
||||
#define ZSWR15_SYNCHUNT_IE 0x10 /* enable SYNC* pin/hunt status int */
|
||||
#define ZSWR15_DCD_IE 0x08 /* enable DCD* pin status int */
|
||||
/* 0x04 unused, must be zero */
|
||||
#define ZSWR15_ZERO_COUNT_IE 0x02 /* enable BRG-counter = 0 status int */
|
||||
/* 0x01 unused, must be zero */
|
||||
|
||||
/*
|
||||
* Bits in Read Register 0 (`Transmit/Receive Buffer Status and External
|
||||
* Status').
|
||||
*/
|
||||
#define ZSRR0_BREAK 0x80 /* break/abort detected */
|
||||
#define ZSRR0_TXUNDER 0x40 /* transmit underrun/EOM (sync) */
|
||||
#define ZSRR0_CTS 0x20 /* clear to send */
|
||||
#define ZSRR0_SYNC_HUNT 0x10 /* sync/hunt (sync mode) */
|
||||
#define ZSRR0_DCD 0x08 /* data carrier detect */
|
||||
#define ZSRR0_TX_READY 0x04 /* transmit buffer empty */
|
||||
#define ZSRR0_ZERO_COUNT 0x02 /* zero count in baud clock */
|
||||
#define ZSRR0_RX_READY 0x01 /* received character ready */
|
||||
|
||||
/*
|
||||
* Bits in Read Register 1 (the Zilog book does not name this one).
|
||||
*/
|
||||
#define ZSRR1_EOF 0x80 /* end of frame (SDLC mode) */
|
||||
#define ZSRR1_FE 0x40 /* CRC/framing error */
|
||||
#define ZSRR1_DO 0x20 /* data (receiver) overrun */
|
||||
#define ZSRR1_PE 0x10 /* parity error */
|
||||
#define ZSRR1_RC0 0x08 /* residue code 0 (SDLC mode) */
|
||||
#define ZSRR1_RC1 0x04 /* residue code 1 (SDLC mode) */
|
||||
#define ZSRR1_RC2 0x02 /* residue code 2 (SDLC mode) */
|
||||
#define ZSRR1_ALL_SENT 0x01 /* all chars out of xmitter (async) */
|
||||
|
||||
/*
|
||||
* Read Register 2 in B channel contains status bits if VECTOR_INCL_STAT
|
||||
* is set.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bits in Read Register 3 (`Interrupt Pending'). Only channel A
|
||||
* has an RR3.
|
||||
*/
|
||||
/* 0x80 unused, returned as 0 */
|
||||
/* 0x40 unused, returned as 0 */
|
||||
#define ZSRR3_IP_A_RX 0x20 /* channel A recv int pending */
|
||||
#define ZSRR3_IP_A_TX 0x10 /* channel A xmit int pending */
|
||||
#define ZSRR3_IP_A_STAT 0x08 /* channel A status int pending */
|
||||
#define ZSRR3_IP_B_RX 0x04 /* channel B recv int pending */
|
||||
#define ZSRR3_IP_B_TX 0x02 /* channel B xmit int pending */
|
||||
#define ZSRR3_IP_B_STAT 0x01 /* channel B status int pending */
|
||||
|
||||
/*
|
||||
* Bits in Read Register 10 (`contains some miscellaneous status bits').
|
||||
*/
|
||||
#define ZSRR10_1_CLOCK_MISSING 0x80 /* 1 clock edge missing (FM mode) */
|
||||
#define ZSRR10_2_CLOCKS_MISSING 0x40 /* 2 clock edges missing (FM mode) */
|
||||
/* 0x20 unused */
|
||||
#define ZSRR10_LOOP_SENDING 0x10 /* xmitter controls loop (SDLC loop) */
|
||||
/* 0x08 unused */
|
||||
/* 0x04 unused */
|
||||
#define ZSRR10_ON_LOOP 0x02 /* SCC is on loop (SDLC/X.21 modes) */
|
||||
|
||||
/*
|
||||
* Bits in Read Register 15. This register is one of the few that
|
||||
* simply reads back the corresponding Write Register.
|
||||
*/
|
||||
#define ZSRR15_BREAK_IE 0x80 /* break/abort status int enable */
|
||||
#define ZSRR15_TXUEOM_IE 0x40 /* TX underrun/EOM status int enable */
|
||||
#define ZSRR15_CTS_IE 0x20 /* CTS* pin status int enable */
|
||||
#define ZSRR15_SYNCHUNT_IE 0x10 /* SYNC* pin/hunt status int enable */
|
||||
#define ZSRR15_DCD_IE 0x08 /* DCD* pin status int enable */
|
||||
/* 0x04 unused, returned as zero */
|
||||
#define ZSRR15_ZERO_COUNT_IE 0x02 /* BRG-counter = 0 status int enable */
|
||||
/* 0x01 unused, returned as zero */
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* 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
|
||||
*
|
||||
* from: Header: zsvar.h,v 1.7 92/11/26 01:28:04 torek Exp (LBL)
|
||||
* $Id: zsvar.h,v 1.1 1994/02/23 08:29:05 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Software state, per zs channel.
|
||||
*
|
||||
* The zs chip has insufficient buffering, so we provide a software
|
||||
* buffer using a two-level interrupt scheme. The hardware (high priority)
|
||||
* interrupt simply grabs the `cause' of the interrupt and stuffs it into
|
||||
* a ring buffer. It then schedules a software interrupt; the latter
|
||||
* empties the ring as fast as it can, hoping to avoid overflow.
|
||||
*
|
||||
* Interrupts can happen because of:
|
||||
* - received data;
|
||||
* - transmit pseudo-DMA done; and
|
||||
* - status change.
|
||||
* These are all stored together in the (single) ring. The size of the
|
||||
* ring is a power of two, to make % operations fast. Since we need two
|
||||
* bits to distinguish the interrupt type, and up to 16 for the received
|
||||
* data plus RR1 status, we use 32 bits per ring entry.
|
||||
*
|
||||
* When the value is a character + RR1 status, the character is in the
|
||||
* upper 8 bits of the RR1 status.
|
||||
*/
|
||||
#define ZLRB_RING_SIZE 256 /* ZS line ring buffer size */
|
||||
#define ZLRB_RING_MASK 255 /* mask for same */
|
||||
|
||||
/* 0 is reserved (means "no interrupt") */
|
||||
#define ZRING_RINT 1 /* receive data interrupt */
|
||||
#define ZRING_XINT 2 /* transmit done interrupt */
|
||||
#define ZRING_SINT 3 /* status change interrupt */
|
||||
|
||||
#define ZRING_TYPE(x) ((x) & 3)
|
||||
#define ZRING_VALUE(x) ((x) >> 8)
|
||||
#define ZRING_MAKE(t, v) ((t) | (v) << 8)
|
||||
|
||||
struct zs_chanstate {
|
||||
struct zs_chanstate *cs_next; /* linked list for zshard() */
|
||||
volatile struct zschan *cs_zc; /* points to hardware regs */
|
||||
int cs_unit; /* unit number */
|
||||
struct tty *cs_ttyp; /* ### */
|
||||
|
||||
/*
|
||||
* We must keep a copy of the write registers as they are
|
||||
* mostly write-only and we sometimes need to set and clear
|
||||
* individual bits (e.g., in WR3). Not all of these are
|
||||
* needed but 16 bytes is cheap and this makes the addressing
|
||||
* simpler. Unfortunately, we can only write to some registers
|
||||
* when the chip is not actually transmitting, so whenever
|
||||
* we are expecting a `transmit done' interrupt the preg array
|
||||
* is allowed to `get ahead' of the current values. In a
|
||||
* few places we must change the current value of a register,
|
||||
* rather than (or in addition to) the pending value; for these
|
||||
* cs_creg[] contains the current value.
|
||||
*/
|
||||
u_char cs_creg[16]; /* current values */
|
||||
u_char cs_preg[16]; /* pending values */
|
||||
u_char cs_heldchange; /* change pending (creg != preg) */
|
||||
u_char cs_rr0; /* last rr0 processed */
|
||||
|
||||
/* pure software data, per channel */
|
||||
char cs_softcar; /* software carrier */
|
||||
char cs_conk; /* is console keyboard, decode L1-A */
|
||||
char cs_brkabort; /* abort (as if via L1-A) on BREAK */
|
||||
char cs_kgdb; /* enter debugger on frame char */
|
||||
char cs_consio; /* port does /dev/console I/O */
|
||||
char cs_xxx; /* (spare) */
|
||||
int cs_speed; /* default baud rate (from ROM) */
|
||||
|
||||
/*
|
||||
* The transmit byte count and address are used for pseudo-DMA
|
||||
* output in the hardware interrupt code. PDMA can be suspended
|
||||
* to get pending changes done; heldtbc is used for this. It can
|
||||
* also be stopped for ^S; this sets TS_TTSTOP in tp->t_state.
|
||||
*/
|
||||
int cs_tbc; /* transmit byte count */
|
||||
caddr_t cs_tba; /* transmit buffer address */
|
||||
int cs_heldtbc; /* held tbc while xmission stopped */
|
||||
|
||||
/*
|
||||
* Printing an overrun error message often takes long enough to
|
||||
* cause another overrun, so we only print one per second.
|
||||
*/
|
||||
long cs_rotime; /* time of last ring overrun */
|
||||
long cs_fotime; /* time of last fifo overrun */
|
||||
|
||||
/*
|
||||
* The ring buffer.
|
||||
*/
|
||||
u_int cs_rbget; /* ring buffer `get' index */
|
||||
volatile u_int cs_rbput; /* ring buffer `put' index */
|
||||
int cs_rbuf[ZLRB_RING_SIZE];/* type, value pairs */
|
||||
};
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#define ZS_READ(c, r) ((c)->zc_csr = (r), zsdelay(5), (c)->zc_csr, zsdelay(5))
|
||||
#define ZS_WRITE(c, r, v) ((c)->zc_csr = (r), zsdelay(5), (c)->zc_csr = (v), zsdelay(5))
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/include/Attic/control.h,v 1.8 1994/02/04 08:19:51 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/include/Attic/control.h,v 1.9 1994/02/23 08:29:13 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -69,6 +69,15 @@
|
|||
#define CONTEXT_NUM 0x8
|
||||
#define CONTEXT_MASK 0x7
|
||||
|
||||
#define SYSTEM_ENAB_DIAG 0x01
|
||||
#define SYSTEM_ENAB_FPA 0x02
|
||||
#define SYSTEM_ENAB_COPY 0x04
|
||||
#define SYSTEM_ENAB_VIDEO 0x08
|
||||
#define SYSTEM_ENAB_CACHE 0x10
|
||||
#define SYSTEM_ENAB_SVDMA 0x20
|
||||
#define SYSTEM_ENAB_FPP 0x40
|
||||
#define SYSTEM_ENAB_BOOT 0x80
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
void control_copy_byte __P((char *, char *, int ));
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/include/mon.h,v 1.11 1994/02/04 08:20:00 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/include/mon.h,v 1.12 1994/02/23 08:29:15 glass Exp $
|
||||
*/
|
||||
/*
|
||||
* This file derived from kernel/mach/sun3.md/machMon.h from the
|
||||
|
@ -357,6 +357,7 @@ extern void Mach_MonTrap _ARGS_((Address address_to_trap_to));
|
|||
|
||||
#define mon_printf (romVectorPtr->printf)
|
||||
#define mon_putchar (romVectorPtr->putChar)
|
||||
#define mon_may_getchar (romVectorPtr->mayGet)
|
||||
#define mon_exit_to_mon (romVectorPtr->exitToMon)
|
||||
#define mon_reboot (romVectorPtr->exitToMon)
|
||||
#define mon_panic(x) { mon_printf(x); mon_exit_to_mon();}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/include/Attic/obio.h,v 1.6 1994/02/04 08:20:02 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/include/Attic/obio.h,v 1.7 1994/02/23 08:29:17 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -39,7 +39,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#define OBIO_KEYBD_MS 0x00000000
|
||||
#define OBIO_ZS 0x00020000
|
||||
#define OBIO_EEPROM 0x00040000
|
||||
|
|
|
@ -175,7 +175,8 @@
|
|||
#define splnet() spl3()
|
||||
#define splbio() spl2()
|
||||
#define splimp() spl6()
|
||||
#define spltty() spl6()
|
||||
#define spltty() spl2()
|
||||
#define splzs( ) spl6()
|
||||
#define splclock() spl5()
|
||||
#define splstatclock() splclock()
|
||||
#define splvm() spl2()
|
||||
|
|
|
@ -175,7 +175,8 @@
|
|||
#define splnet() spl3()
|
||||
#define splbio() spl2()
|
||||
#define splimp() spl6()
|
||||
#define spltty() spl6()
|
||||
#define spltty() spl2()
|
||||
#define splzs( ) spl6()
|
||||
#define splclock() spl5()
|
||||
#define splstatclock() splclock()
|
||||
#define splvm() spl2()
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
/*
|
||||
* $Id: ptrace.h,v 1.1 1994/01/08 19:08:52 cgd Exp $
|
||||
* $Id: ptrace.h,v 1.2 1994/02/23 08:29:22 glass Exp $
|
||||
*/
|
||||
|
||||
/* Just use the common m68k definition */
|
||||
#include <m68k/ptrace.h>
|
||||
/*
|
||||
* $Id: ptrace.h,v 1.2 1994/02/23 08:29:22 glass Exp $
|
||||
*/
|
||||
|
||||
/* Just use the common m68k definition */
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
/*
|
||||
* $Id: varargs.h,v 1.1 1994/01/27 15:26:31 mycroft Exp $
|
||||
* $Id: varargs.h,v 1.2 1994/02/23 08:29:24 glass Exp $
|
||||
*/
|
||||
|
||||
/* Just use the common m68k definition */
|
||||
#include <m68k/varargs.h>
|
||||
/*
|
||||
* $Id: varargs.h,v 1.2 1994/02/23 08:29:24 glass Exp $
|
||||
*/
|
||||
|
||||
/* Just use the common m68k definition */
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/autoconf.c,v 1.5 1994/02/04 08:20:19 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/autoconf.c,v 1.6 1994/02/23 08:29:31 glass Exp $
|
||||
*/
|
||||
/*
|
||||
* Setup the system to run on the current machine.
|
||||
|
@ -90,8 +90,8 @@ void configure()
|
|||
{
|
||||
int root_found;
|
||||
|
||||
boothowto = RB_SINGLE;
|
||||
isr_init();
|
||||
|
||||
root_found = config_rootfound("mainbus", NULL);
|
||||
if (!root_found)
|
||||
panic("configure: autoconfig failed, no device tree root found");
|
||||
|
|
|
@ -1 +1 @@
|
|||
revision 1.7 intentionally removed
|
||||
revision 1.8 intentionally removed
|
||||
|
|
|
@ -56,12 +56,17 @@
|
|||
|
||||
#include "prom.h"
|
||||
|
||||
#include "zs.h"
|
||||
|
||||
int promcnprobe(), promcninit(), promcngetc(), promcnputc();
|
||||
int zscnprobe(), zscninit(), zscngetc(), zscnputc();
|
||||
|
||||
struct consdev constab[] = {
|
||||
#if NPROM
|
||||
{promcnprobe, promcninit, promcngetc, promcnputc},
|
||||
#endif
|
||||
#if NZS
|
||||
{zscnprobe, zscninit, zscngetc, zscnputc},
|
||||
#endif
|
||||
{ 0 },
|
||||
};
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/control.h,v 1.8 1994/02/04 08:19:51 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/control.h,v 1.9 1994/02/23 08:29:13 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -69,6 +69,15 @@
|
|||
#define CONTEXT_NUM 0x8
|
||||
#define CONTEXT_MASK 0x7
|
||||
|
||||
#define SYSTEM_ENAB_DIAG 0x01
|
||||
#define SYSTEM_ENAB_FPA 0x02
|
||||
#define SYSTEM_ENAB_COPY 0x04
|
||||
#define SYSTEM_ENAB_VIDEO 0x08
|
||||
#define SYSTEM_ENAB_CACHE 0x10
|
||||
#define SYSTEM_ENAB_SVDMA 0x20
|
||||
#define SYSTEM_ENAB_FPP 0x40
|
||||
#define SYSTEM_ENAB_BOOT 0x80
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
void control_copy_byte __P((char *, char *, int ));
|
||||
|
|
|
@ -95,6 +95,8 @@ main()
|
|||
printf("#define\tCONTEXT_0 %d\n", CONTEXT_0);
|
||||
printf("#define\tCONTEXT_REG %d\n", CONTEXT_REG);
|
||||
printf("#define\tCONTEXT_NUM %d\n", CONTEXT_NUM);
|
||||
printf("#define\tSYSTEM_ENAB %d\n", SYSTEM_ENAB);
|
||||
printf("#define\tSYSTEM_ENAB_FPP %d\n", SYSTEM_ENAB_FPP);
|
||||
printf("#define\tSEGMAP_BASE %d\n", SEGMAP_BASE);
|
||||
printf("#define\tNBPG %d\n", NBPG);
|
||||
printf("#define\tNBSG %d\n", NBSG);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/isr.c,v 1.4 1994/02/04 08:20:58 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/isr.c,v 1.5 1994/02/23 08:29:40 glass Exp $
|
||||
*/
|
||||
|
||||
#include "param.h"
|
||||
|
@ -39,6 +39,7 @@
|
|||
#include "machine/isr.h"
|
||||
|
||||
#include "vector.h"
|
||||
#include "interreg.h"
|
||||
|
||||
/*
|
||||
* Justification:
|
||||
|
@ -49,6 +50,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
extern char *interrupt_reg;
|
||||
|
||||
extern void level0intr(), level1intr(), level2intr(), level3intr(),
|
||||
level4intr(), level5intr(), level6intr(), level7intr();
|
||||
|
@ -131,6 +133,60 @@ void isr_add(level, handler, arg)
|
|||
isr_activate(level);
|
||||
}
|
||||
|
||||
|
||||
void isr_soft_request(level)
|
||||
int level;
|
||||
{
|
||||
u_char bit, reg_val;
|
||||
int s;
|
||||
|
||||
if ((level < 1) || (level > 3))
|
||||
panic("isr_soft_request");
|
||||
s = splhigh();
|
||||
reg_val = *interrupt_reg;
|
||||
*interrupt_reg &= ~IREG_ALL_ENAB;
|
||||
switch(level) {
|
||||
case 1:
|
||||
bit = IREG_SOFT_ENAB_1;
|
||||
break;
|
||||
case 2:
|
||||
bit = IREG_SOFT_ENAB_2;
|
||||
break;
|
||||
case 3:
|
||||
bit = IREG_SOFT_ENAB_3;
|
||||
break;
|
||||
}
|
||||
*interrupt_reg |= bit;
|
||||
*interrupt_reg |= IREG_ALL_ENAB;
|
||||
splx(s);
|
||||
}
|
||||
void isr_soft_clear(level)
|
||||
int level;
|
||||
{
|
||||
u_char bit, reg_val;
|
||||
int s;
|
||||
|
||||
if ((level < 1) || (level > 3))
|
||||
panic("isr_soft_clear");
|
||||
s = splhigh();
|
||||
reg_val = *interrupt_reg;
|
||||
*interrupt_reg &= ~IREG_ALL_ENAB;
|
||||
switch(level) {
|
||||
case 1:
|
||||
bit = IREG_SOFT_ENAB_1;
|
||||
break;
|
||||
case 2:
|
||||
bit = IREG_SOFT_ENAB_2;
|
||||
break;
|
||||
case 3:
|
||||
bit = IREG_SOFT_ENAB_3;
|
||||
break;
|
||||
}
|
||||
*interrupt_reg &= ~bit;
|
||||
*interrupt_reg |= IREG_ALL_ENAB;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void intrhand(sr)
|
||||
int sr;
|
||||
{
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/locore.s,v 1.14 1994/02/04 08:21:00 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/locore.s,v 1.15 1994/02/23 08:29:42 glass Exp $
|
||||
*/
|
||||
#include "assym.s"
|
||||
#include "../include/asm.h"
|
||||
|
@ -100,6 +100,11 @@ bsszero: clrl a0@
|
|||
cmpl a0, a1
|
||||
bne bsszero
|
||||
|
||||
fpu_setup:
|
||||
movsb SYSTEM_ENAB, d0 | read enable register
|
||||
orb #SYSTEM_ENAB_FPP, d0 | set fpu bit
|
||||
movsb d0, SYSTEM_ENAB
|
||||
|
||||
final_before_main:
|
||||
|
||||
lea tmpstk, sp | switch to tmpstack
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/locore2.c,v 1.15 1994/02/04 08:21:07 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/locore2.c,v 1.16 1994/02/23 08:29:50 glass Exp $
|
||||
*/
|
||||
|
||||
#include "systm.h"
|
||||
|
@ -533,8 +533,6 @@ void pte_print(pte)
|
|||
mon_printf("pte: ");
|
||||
if (pte & PG_VALID) {
|
||||
mon_printf("Valid ");
|
||||
if (pte & PG_WRITE)
|
||||
mon_printf("Write ");
|
||||
if (pte & PG_WRITE)
|
||||
mon_printf("Write ");
|
||||
if (pte & PG_SYSTEM)
|
||||
|
@ -594,13 +592,10 @@ void sun3_bootstrap()
|
|||
initialize_vector_table(); /* point interrupts/exceptions to our table */
|
||||
|
||||
sun3_vm_init(); /* handle kernel mapping problems, etc */
|
||||
printf("sun3 vm initialization complete\n");
|
||||
|
||||
pmap_bootstrap(); /* */
|
||||
printf("pmap module bootstrapped\n");
|
||||
|
||||
internal_configure(); /* stuff that can't wait for configure() */
|
||||
|
||||
astpending =0;
|
||||
printf("calling main()\n");
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/m68k.s,v 1.10 1994/02/04 08:21:01 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/m68k.s,v 1.11 1994/02/23 08:29:43 glass Exp $
|
||||
*/
|
||||
|
||||
ENTRY(getvbr)
|
||||
|
@ -187,3 +187,30 @@ ENTRY(longjmp)
|
|||
movl a0@,sp@
|
||||
moveq #1,d0
|
||||
rts
|
||||
|
||||
#ifdef FPCOPROC
|
||||
/*
|
||||
* Save and restore 68881 state.
|
||||
* Pretty awful looking since our assembler does not
|
||||
* recognize FP mnemonics.
|
||||
*/
|
||||
ENTRY(m68881_save)
|
||||
movl sp@(4),a0 | save area pointer
|
||||
fsave a0@ | save state
|
||||
tstb a0@ | null state frame?
|
||||
jeq Lm68881sdone | yes, all done
|
||||
fmovem fp0-fp7,a0@(216) | save FP general registers
|
||||
fmovem fpcr/fpsr/fpi,a0@(312) | save FP control registers
|
||||
Lm68881sdone:
|
||||
rts
|
||||
|
||||
ENTRY(m68881_restore)
|
||||
movl sp@(4),a0 | save area pointer
|
||||
tstb a0@ | null state frame?
|
||||
jeq Lm68881rdone | yes, easy
|
||||
fmovem a0@(312),fpcr/fpsr/fpi | restore FP control registers
|
||||
fmovem a0@(216),fp0-fp7 | restore FP general registers
|
||||
Lm68881rdone:
|
||||
frestore a0@ | restore state
|
||||
rts
|
||||
#endif
|
||||
|
|
|
@ -106,7 +106,7 @@ int bufpages = 0;
|
|||
int *nofault;
|
||||
|
||||
extern vm_offset_t u_area_va;
|
||||
caddr_t allocsys();
|
||||
caddr_t allocsys __P((caddr_t));
|
||||
|
||||
void identifycpu()
|
||||
{
|
||||
|
@ -229,19 +229,18 @@ void cpu_startup()
|
|||
callfree = callout;
|
||||
for (i = 1; i < ncallout; i++)
|
||||
callout[i-1].c_next = &callout[i];
|
||||
callout[i-1].c_next = NULL;
|
||||
|
||||
printf("avail mem = %d\n", ptoa(vm_page_free_count));
|
||||
printf("using %d buffers containing %d bytes of memory\n",
|
||||
nbuf, bufpages * CLBYTES);
|
||||
|
||||
|
||||
|
||||
printf("avail mem = %d\n", ptoa(vm_page_free_count));
|
||||
/* initcpu();*/
|
||||
/*
|
||||
* Set up buffers, so they can be used to read disk labels.
|
||||
*/
|
||||
bufinit();
|
||||
|
||||
/*
|
||||
* Configure the system.
|
||||
*/
|
||||
|
@ -267,6 +266,7 @@ allocsys(v)
|
|||
|
||||
#define valloc(name, type, num) \
|
||||
v = (caddr_t)(((name) = (type *)v) + (num))
|
||||
|
||||
#ifdef REAL_CLISTS
|
||||
valloc(cfree, struct cblock, nclist);
|
||||
#endif
|
||||
|
@ -651,7 +651,8 @@ sendsig(catcher, sig, mask, code)
|
|||
kfp->sf_scp = hkfp->hsf_scp;
|
||||
}
|
||||
#endif
|
||||
(void) copyout((caddr_t)kfp, (caddr_t)fp, fsize);
|
||||
if (copyout((caddr_t)kfp, (caddr_t)fp, fsize))
|
||||
panic("sendsig: unable to copyout sigframe\n");
|
||||
frame->f_regs[SP] = (int)fp;
|
||||
#ifdef DEBUG
|
||||
if (sigdebug & SDB_FOLLOW)
|
||||
|
@ -748,7 +749,8 @@ sun_sendsig(catcher, sig, mask, code)
|
|||
kfp.ssf_sc.sc_sp = frame->f_regs[SP];
|
||||
kfp.ssf_sc.sc_pc = frame->f_pc;
|
||||
kfp.ssf_sc.sc_ps = frame->f_sr;
|
||||
(void) copyout((caddr_t)&kfp, (caddr_t)fp, fsize);
|
||||
if (copyout((caddr_t)&kfp, (caddr_t)fp, fsize))
|
||||
panic("sendsig: copying out signal context\n");
|
||||
frame->f_regs[SP] = (int)fp;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -862,9 +864,11 @@ sigreturn(p, uap, retval)
|
|||
p->p_sigmask = scp->sc_mask &~ sigcantmask;
|
||||
frame = (struct frame *) p->p_regs;
|
||||
frame->f_regs[SP] = scp->sc_sp;
|
||||
#ifdef COMPAT_SUNOS
|
||||
#ifndef COMPAT_SUNOS
|
||||
frame->f_regs[A6] = scp->sc_fp;
|
||||
#else
|
||||
if (p->p_emul != EMUL_SUNOS)
|
||||
frame->f_regs[A6] = scp->sc_fp;
|
||||
frame->f_regs[A6] = scp->sc_fp;
|
||||
#endif
|
||||
frame->f_pc = scp->sc_pc;
|
||||
frame->f_sr = scp->sc_ps;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/obio.h,v 1.6 1994/02/04 08:20:02 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/obio.h,v 1.7 1994/02/23 08:29:17 glass Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -39,7 +39,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#define OBIO_KEYBD_MS 0x00000000
|
||||
#define OBIO_ZS 0x00020000
|
||||
#define OBIO_EEPROM 0x00040000
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/pmap.c,v 1.17 1994/02/04 08:21:04 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/pmap.c,v 1.18 1994/02/23 08:29:48 glass Exp $
|
||||
*/
|
||||
#include "systm.h"
|
||||
#include "param.h"
|
||||
|
@ -104,13 +104,8 @@ vm_offset_t avail_start, avail_end;
|
|||
|
||||
#define splpmap splbio
|
||||
|
||||
#ifdef CONFUSED
|
||||
#define PMAP_LOCK() s = splpmap()
|
||||
#define PMAP_UNLOCK() splx(s)
|
||||
#else
|
||||
#define PMAP_LOCK() /* pmap lock */
|
||||
#define PMAP_UNLOCK() /* pmap unlock */
|
||||
#endif
|
||||
|
||||
#define dequeue_first(val, type, queue) { \
|
||||
val = (type) queue_first(queue); \
|
||||
|
@ -541,6 +536,8 @@ pmeg_t pmeg_allocate_invalid(pmap, va)
|
|||
pmegp->pmeg_reserved = 0;
|
||||
pmegp->pmeg_vpages = 0;
|
||||
enqueue_tail(&pmeg_active_queue, pmegp);
|
||||
if (pmap != kernel_pmap)
|
||||
pmap->pm_segmap[VA_SEGNUM(va)] = pmegp->pmeg_index;
|
||||
return pmegp;
|
||||
}
|
||||
|
||||
|
@ -573,21 +570,21 @@ pmeg_t pmeg_cache(pmap, va, update)
|
|||
|
||||
if (!pmap->pm_segmap || (pmap == kernel_pmap)) return PMEG_NULL;
|
||||
seg = VA_SEGNUM(va);
|
||||
if (seg < NUSEG)
|
||||
if (seg > NUSEG) /* out of range */
|
||||
return PMEG_NULL;
|
||||
if (pmap->pm_segmap[seg] == SEGINV)
|
||||
if (pmap->pm_segmap[seg] == SEGINV) /* nothing cached */
|
||||
return PMEG_NULL;
|
||||
if (update)
|
||||
pmap->pm_segmap[seg] = SEGINV;
|
||||
pmegp = pmeg_p(pmap->pm_segmap[seg]);
|
||||
|
||||
if ((pmegp->pmeg_owner != pmap) ||
|
||||
(pmegp->pmeg_owner_version != pmap->pm_version) ||
|
||||
(pmegp->pmeg_va != va)) return PMEG_NULL; /* cache lookup failed */
|
||||
(pmegp->pmeg_va != va)) {
|
||||
if (update)
|
||||
pmap->pm_segmap[seg] = SEGINV;
|
||||
return PMEG_NULL; /* cache lookup failed */
|
||||
}
|
||||
remqueue(&pmeg_inactive_queue, pmegp);
|
||||
enqueue_tail(&pmeg_active_queue, pmegp);
|
||||
if (update)
|
||||
pmap->pm_segmap[seg] = pmegp->pmeg_index;
|
||||
return pmegp;
|
||||
}
|
||||
|
||||
|
@ -700,12 +697,15 @@ unsigned char pv_link(pmap, pa, va, flags)
|
|||
pv->pv_next = NULL;
|
||||
pv->pv_flags = flags;
|
||||
force_cache_flags(pa, flags);
|
||||
PMAP_UNLOCK();
|
||||
return flags & PV_NC;
|
||||
}
|
||||
for (npv = pv ; npv != NULL; last= npv, npv = npv->pv_next ) {
|
||||
if ((npv->pv_pmap != pmap) || (npv->pv_va != va)) continue;
|
||||
if (flags == npv->pv_flags) /* no change */
|
||||
if (flags == npv->pv_flags) {/* no change */
|
||||
PMAP_UNLOCK();
|
||||
return get_cache_flags(pa);
|
||||
}
|
||||
npv->pv_flags = flags;
|
||||
goto recompute;
|
||||
}
|
||||
|
@ -722,11 +722,13 @@ unsigned char pv_link(pmap, pa, va, flags)
|
|||
if (flags & PV_NC) { /* being NCed, wasn't before */
|
||||
force_cache_flags(pa, flags);
|
||||
pv_change_pte(head, MAKE_PV_REAL(PV_NC), 0);
|
||||
PMAP_UNLOCK();
|
||||
return flags & PV_NC;
|
||||
}
|
||||
nflags = pv_compute_cache(head);
|
||||
force_cache_flags(pa, nflags);
|
||||
pv_change_pte(head, MAKE_PV_REAL(nflags), 0); /* */
|
||||
PMAP_UNLOCK();
|
||||
return nflags & PV_NC;
|
||||
}
|
||||
void pv_change_pte(pv_list, set_bits, clear_bits)
|
||||
|
@ -772,7 +774,9 @@ void pv_unlink(pmap, pa, va)
|
|||
if (!pv_initialized) return;
|
||||
pv_list = pa_to_pvp(pa);
|
||||
if (pv_list->pv_pmap == NULL) {
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pv_unlinking too many times\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -813,7 +817,9 @@ void pv_unlink(pmap, pa, va)
|
|||
}
|
||||
return;
|
||||
}
|
||||
panic("pv_unlink: couldn't find entry");
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pv_unlink: couldn't find entry");
|
||||
#endif
|
||||
}
|
||||
void pv_init()
|
||||
{
|
||||
|
@ -994,6 +1000,9 @@ pmap_destroy(pmap)
|
|||
{
|
||||
int count;
|
||||
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_destroy(%x)\n", pmap);
|
||||
#endif
|
||||
if (pmap == NULL) return;
|
||||
if (pmap == kernel_pmap)
|
||||
panic("pmap: attempted to destroy kernel_pmap");
|
||||
|
@ -1005,6 +1014,9 @@ pmap_destroy(pmap)
|
|||
free((caddr_t)pmap, M_VMPMAP); /* XXXX -- better make sure we
|
||||
it this way allocate */
|
||||
}
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_successful(%x)\n", pmap);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1019,6 +1031,9 @@ pmap_page_protect(pa, prot)
|
|||
{
|
||||
int s;
|
||||
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_page_protect(%x, %x)\n", pa, prot);
|
||||
#endif
|
||||
PMAP_LOCK();
|
||||
switch (prot) {
|
||||
case VM_PROT_ALL:
|
||||
|
@ -1067,7 +1082,7 @@ void pmap_remove_range_mmu(pmap, sva, eva)
|
|||
sme = get_segmap(sva);
|
||||
if (sme == SEGINV) {
|
||||
if (pmap == kernel_pmap) return;
|
||||
pmegp = pmeg_cache(pmap, VA_SEGNUM(sva), PM_UPDATE_CACHE);
|
||||
pmegp = pmeg_cache(pmap, sun3_trunc_seg(va), PM_UPDATE_CACHE);
|
||||
if (!pmegp) goto outta_here;
|
||||
set_segmap(sva, pmegp->pmeg_index);
|
||||
}
|
||||
|
@ -1150,7 +1165,10 @@ void pmap_remove_range(pmap, sva, eva)
|
|||
*/
|
||||
|
||||
if ((pmap != kernel_pmap))
|
||||
if (get_pmeg_cache(pmap, VA_SEGNUM(sva)) == SEGINV) return;
|
||||
if (get_pmeg_cache(pmap, VA_SEGNUM(sva)) == SEGINV) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pmap == kernel_pmap) ||
|
||||
(pmap->pm_context)) {
|
||||
pmap_remove_range_mmu(pmap, sva, eva);
|
||||
|
@ -1183,6 +1201,9 @@ void pmap_remove(pmap, sva, eva)
|
|||
if (pmap == NULL)
|
||||
return;
|
||||
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_remove(%x, %x, %x)\n", pmap, sva, eva);
|
||||
#endif
|
||||
/* do something about contexts */
|
||||
if (pmap == kernel_pmap) {
|
||||
if (sva < VM_MIN_KERNEL_ADDRESS)
|
||||
|
@ -1191,8 +1212,8 @@ void pmap_remove(pmap, sva, eva)
|
|||
eva = VM_MAX_KERNEL_ADDRESS;
|
||||
}
|
||||
else {
|
||||
if (eva > VM_MAX_ADDRESS)
|
||||
eva = VM_MAX_ADDRESS;
|
||||
if (eva > VM_MAXUSER_ADDRESS)
|
||||
eva = VM_MAXUSER_ADDRESS;
|
||||
}
|
||||
PMAP_LOCK();
|
||||
va = sva;
|
||||
|
@ -1320,6 +1341,7 @@ void pmap_enter_user(pmap, va, pa, prot, wired, pte_proto, mem_type)
|
|||
panic("pmap: user trying to allocate virtual space above itself\n");
|
||||
if (wired)
|
||||
printf("pmap_enter_user: attempt to wire user page, ignored\n");
|
||||
|
||||
pte_proto |= MAKE_PGTYPE(PG_MMEM); /* unnecessary */
|
||||
PMAP_LOCK();
|
||||
saved_context = get_context();
|
||||
|
@ -1332,7 +1354,7 @@ void pmap_enter_user(pmap, va, pa, prot, wired, pte_proto, mem_type)
|
|||
if (sme == SEGINV) {
|
||||
pmegp = pmeg_cache(pmap, sun3_trunc_seg(va),PM_UPDATE_CACHE);
|
||||
if (!pmegp) /* no cached pmeg */
|
||||
pmegp = pmeg_allocate_invalid(pmap, va);
|
||||
pmegp = pmeg_allocate_invalid(pmap, sun3_trunc_seg(va));
|
||||
set_segmap(va,pmegp->pmeg_index);
|
||||
} else
|
||||
pmegp = pmeg_p(sme);
|
||||
|
@ -1386,7 +1408,10 @@ pmap_enter(pmap, va, pa, prot, wired)
|
|||
int s;
|
||||
|
||||
if (pmap == NULL) return;
|
||||
|
||||
#if defined(PMAP_ENTER_DEBUG) || defined(PMAP_DEBUG)
|
||||
printf("pmap_enter(%x, %x, %x, %x, %x)\n",
|
||||
pmap, va, pa, prot, wired);
|
||||
#endif
|
||||
mem_type = pa & PMAP_MEMMASK;
|
||||
pte_proto = PG_VALID | pmap_pte_prot(prot) | (pa & PMAP_NC ? PG_NC : 0);
|
||||
pa &= ~PMAP_SPECMASK;
|
||||
|
@ -1413,7 +1438,9 @@ pmap_clear_modify(pa)
|
|||
int s;
|
||||
|
||||
if (!pv_initialized) return;
|
||||
|
||||
#if defined(PMAP_DEBUG) || defined(PMPA_COW_DEBUG)
|
||||
printf("pmap_clear_modified: %x\n", pa);
|
||||
#endif
|
||||
PMAP_LOCK();
|
||||
pv_modified_table[PA_PGNUM(pa)] = 0;
|
||||
pv_change_pte(&pv_head_table[PA_PGNUM(pa)], 0, PG_MOD);
|
||||
|
@ -1425,6 +1452,9 @@ pmap_is_modified(pa)
|
|||
{
|
||||
int s;
|
||||
|
||||
#if defined(PMAP_DEBUG) || defined(PMPA_COW_DEBUG)
|
||||
printf("pmap_is_modified: %x\n", pa);
|
||||
#endif
|
||||
if (!pv_initialized) return 0;
|
||||
if (pv_modified_table[PA_PGNUM(pa)]) return 1;
|
||||
PMAP_LOCK();
|
||||
|
@ -1439,6 +1469,9 @@ void pmap_clear_reference(pa)
|
|||
int s;
|
||||
|
||||
if (!pv_initialized) return;
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_clear_referenced: %x\n", pa);
|
||||
#endif
|
||||
PMAP_LOCK();
|
||||
pv_remove_all(pa);
|
||||
PMAP_UNLOCK();
|
||||
|
@ -1448,6 +1481,7 @@ boolean_t
|
|||
pmap_is_referenced(pa)
|
||||
vm_offset_t pa;
|
||||
{
|
||||
printf("pmap_is_referenced: %x\n", pa);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1458,20 +1492,33 @@ void pmap_activate(pmap, pcbp)
|
|||
{
|
||||
int s;
|
||||
|
||||
PMAP_LOCK();
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_activate(%x, %x)\n", pmap, pcbp);
|
||||
#endif
|
||||
if (pmap->pm_context) {
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_activate(%x, %x) switching to context %d\n", pmap, pcbp,
|
||||
pmap->pm_context->context_num);
|
||||
#endif
|
||||
set_context(pmap->pm_context->context_num);
|
||||
PMAP_UNLOCK();
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_activate(%x, %x) completed\n", pmap, pcbp);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
context_allocate(pmap);
|
||||
set_context(pmap->pm_context->context_num);
|
||||
PMAP_UNLOCK();
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_activate(%x, %x) completed\n", pmap, pcbp);
|
||||
#endif
|
||||
}
|
||||
void pmap_deactivate(pmap, pcbp)
|
||||
pmap_t pmap;
|
||||
struct pcb *pcbp;
|
||||
{
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap_deactivate(%x, %x)\n", pmap, pcbp);
|
||||
#endif
|
||||
enqueue_tail(&context_active_queue,
|
||||
(queue_entry_t) pmap->pm_context);
|
||||
}
|
||||
|
@ -1489,7 +1536,9 @@ pmap_change_wiring(pmap, va, wired)
|
|||
vm_offset_t va;
|
||||
boolean_t wired;
|
||||
{
|
||||
#ifdef PMAP_DEBUG
|
||||
printf("pmap: call to pmap_change_wiring(). ignoring.\n");
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* Copy the range specified by src_addr/len
|
||||
|
@ -1519,6 +1568,9 @@ void pmap_copy_page(src, dst)
|
|||
vm_offset_t pte;
|
||||
int s;
|
||||
|
||||
#if defined(PMAP_DEBUG) || defined(PMPA_COW_DEBUG)
|
||||
printf("pmap_copy_page: %x -> %x\n", src, dst);
|
||||
#endif
|
||||
PMAP_LOCK();
|
||||
pte = PG_VALID |PG_SYSTEM|PG_WRITE|PG_NC|PG_MMEM| PA_PGNUM(src);
|
||||
set_pte(tmp_vpages[0], pte);
|
||||
|
@ -1545,6 +1597,7 @@ pmap_extract(pmap, va)
|
|||
vm_offset_t pte;
|
||||
int s;
|
||||
|
||||
PMAP_LOCK();
|
||||
if (pmap == kernel_pmap) {
|
||||
sme = get_segmap(va);
|
||||
if (sme == SEGINV)
|
||||
|
@ -1723,6 +1776,9 @@ pmap_protect(pmap, sva, eva, prot)
|
|||
if (eva > VM_MAX_ADDRESS)
|
||||
eva = VM_MAX_ADDRESS;
|
||||
}
|
||||
#if defined(PMAP_DEBUG) || defined(PMPA_COW_DEBUG)
|
||||
printf("pmap_protect(%x, %x, %x, %x)\n", pmap, sva, eva, prot);
|
||||
#endif
|
||||
if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
|
||||
pmap_remove(pmap, sva, eva);
|
||||
return;
|
||||
|
@ -1763,6 +1819,9 @@ void pmap_zero_page(pa)
|
|||
vm_offset_t pte;
|
||||
int s;
|
||||
|
||||
#if defined(PMAP_DEBUG) || defined(PMAP_COW_DEBUG)
|
||||
printf("pmap_zero_page: %x\n", pa);
|
||||
#endif
|
||||
PMAP_LOCK();
|
||||
pte = PG_VALID |PG_SYSTEM|PG_WRITE|PG_NC|PG_MMEM| PA_PGNUM(pa);
|
||||
set_pte(tmp_vpages[0], pte);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/sun3_startup.c,v 1.15 1994/02/04 08:21:07 glass Exp $
|
||||
* $Header: /cvsroot/src/sys/arch/sun3/sun3/Attic/sun3_startup.c,v 1.16 1994/02/23 08:29:50 glass Exp $
|
||||
*/
|
||||
|
||||
#include "systm.h"
|
||||
|
@ -533,8 +533,6 @@ void pte_print(pte)
|
|||
mon_printf("pte: ");
|
||||
if (pte & PG_VALID) {
|
||||
mon_printf("Valid ");
|
||||
if (pte & PG_WRITE)
|
||||
mon_printf("Write ");
|
||||
if (pte & PG_WRITE)
|
||||
mon_printf("Write ");
|
||||
if (pte & PG_SYSTEM)
|
||||
|
@ -594,13 +592,10 @@ void sun3_bootstrap()
|
|||
initialize_vector_table(); /* point interrupts/exceptions to our table */
|
||||
|
||||
sun3_vm_init(); /* handle kernel mapping problems, etc */
|
||||
printf("sun3 vm initialization complete\n");
|
||||
|
||||
pmap_bootstrap(); /* */
|
||||
printf("pmap module bootstrapped\n");
|
||||
|
||||
internal_configure(); /* stuff that can't wait for configure() */
|
||||
|
||||
astpending =0;
|
||||
printf("calling main()\n");
|
||||
}
|
||||
|
|
|
@ -73,6 +73,12 @@
|
|||
#include "compat/sunos/sun_syscall.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* Chris's new syscall debug stuff
|
||||
*/
|
||||
|
||||
struct sysent sysent[];
|
||||
int nsysent;
|
||||
#ifdef COMPAT_SUNOS
|
||||
|
@ -517,6 +523,8 @@ syscall(code, frame)
|
|||
int rval[2];
|
||||
struct timeval syst;
|
||||
struct sysent *systab;
|
||||
extern char *syscallnames[];
|
||||
char **sysnames;
|
||||
#ifdef HPUXCOMPAT
|
||||
extern struct sysent hpuxsysent[];
|
||||
extern int hpuxnsysent, notimp();
|
||||
|
@ -535,7 +543,7 @@ syscall(code, frame)
|
|||
|
||||
systab = sun_sysent;
|
||||
numsys = nsun_sysent;
|
||||
|
||||
sysnames = sun_syscallnames;
|
||||
/* SunOS passes the syscall-number on the stack, whereas
|
||||
BSD passes it in D0. So, we have to get the real "code"
|
||||
from the stack, and clean up the stack, as SunOS glue
|
||||
|
@ -559,6 +567,7 @@ syscall(code, frame)
|
|||
case EMUL_HPUX:
|
||||
systab = hpuxsysent;
|
||||
numsys = hpuxnsysent;
|
||||
sysnames = hpuxnsyscallnames;
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
@ -566,7 +575,7 @@ syscall(code, frame)
|
|||
default:
|
||||
systab = sysent;
|
||||
numsys = nsysent;
|
||||
|
||||
sysnames = syscallnames;
|
||||
}
|
||||
params = (caddr_t)frame.f_regs[SP] + sizeof(int);
|
||||
if (code == 0) { /* indir */
|
||||
|
|
|
@ -119,7 +119,11 @@ Lbe10:
|
|||
*/
|
||||
sun3_mmu_specific:
|
||||
clrl d0 | make sure top bits are cleard too
|
||||
movl d1, sp@- | save d1
|
||||
moveq #FC_CONTROL, d1 | need to set source to control space
|
||||
movc d1, sfc | control space source established
|
||||
movsb BUSERR_REG, d0 | get value of bus error register
|
||||
movl sp@+, d1 | restore d1
|
||||
btst #5, d0 | test to timeout bit
|
||||
jne Lisberr | if bus error, do it
|
||||
Lismerr:
|
||||
|
|
|
@ -125,9 +125,6 @@ cpu_exit(p)
|
|||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern vm_map_t phys_map;
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue