summaryrefslogtreecommitdiff
path: root/sys/pc98
diff options
context:
space:
mode:
authorcvs2svn <cvs2svn@FreeBSD.org>1999-01-21 00:55:32 +0000
committercvs2svn <cvs2svn@FreeBSD.org>1999-01-21 00:55:32 +0000
commit76b5366091f76c9bc73570149ef5055648fc2c39 (patch)
tree590d020e0f2a5bea6e09d66d951a674443b21d67 /sys/pc98
parent4b4d01da6f07f7754ff6a6e4f5223e9f0984d1a6 (diff)
This commit was manufactured by cvs2svn to create tagrelease/3.0.0
'RELENG_3_0_0_RELEASE'.
Diffstat (limited to 'sys/pc98')
-rw-r--r--sys/pc98/boot/Makefile.inc4
-rw-r--r--sys/pc98/boot/biosboot/Makefile28
-rw-r--r--sys/pc98/boot/biosboot/README.serial6
-rw-r--r--sys/pc98/boot/biosboot/serial.S10
-rw-r--r--sys/pc98/boot/kzipboot/Makefile6
-rw-r--r--sys/pc98/boot/kzipboot/malloc.c6
-rw-r--r--sys/pc98/boot/netboot/Makefile21
-rw-r--r--sys/pc98/boot/rawboot/Makefile7
-rw-r--r--sys/pc98/conf/GENERIC98131
-rw-r--r--sys/pc98/conf/GENERICupgrade204
-rw-r--r--sys/pc98/conf/Makefile.pc9862
-rw-r--r--sys/pc98/conf/SMP-GENERIC98230
-rw-r--r--sys/pc98/conf/devices.pc984
-rw-r--r--sys/pc98/conf/files.pc9876
-rw-r--r--sys/pc98/conf/majors.pc9822
-rw-r--r--sys/pc98/conf/options.pc9868
-rw-r--r--sys/pc98/i386/machdep.c44
-rw-r--r--sys/pc98/i386/trap.c1159
-rw-r--r--sys/pc98/i386/userconfig.c225
-rw-r--r--sys/pc98/pc98/atcompat_diskslice.c4
-rw-r--r--sys/pc98/pc98/clock.c64
-rw-r--r--sys/pc98/pc98/diskslice_machdep.c8
-rw-r--r--sys/pc98/pc98/fd.c467
-rw-r--r--sys/pc98/pc98/if_ed.c33
-rw-r--r--sys/pc98/pc98/if_ed98.h112
-rw-r--r--sys/pc98/pc98/if_fe.c3824
-rw-r--r--sys/pc98/pc98/lpt.c73
-rw-r--r--sys/pc98/pc98/mse.c6
-rw-r--r--sys/pc98/pc98/npx.c30
-rw-r--r--sys/pc98/pc98/pc98.c11
-rw-r--r--sys/pc98/pc98/pc98gdc.c887
-rw-r--r--sys/pc98/pc98/pc98kbd.c1009
-rw-r--r--sys/pc98/pc98/pcaudio.c48
-rw-r--r--sys/pc98/pc98/scvidctl.c582
-rw-r--r--sys/pc98/pc98/sio.c1634
-rw-r--r--sys/pc98/pc98/sioreg.h119
-rw-r--r--sys/pc98/pc98/syscons.c4143
-rw-r--r--sys/pc98/pc98/syscons.h134
-rw-r--r--sys/pc98/pc98/wd.c76
39 files changed, 9457 insertions, 6120 deletions
diff --git a/sys/pc98/boot/Makefile.inc b/sys/pc98/boot/Makefile.inc
index 88916943ec96..c02d4d7980f0 100644
--- a/sys/pc98/boot/Makefile.inc
+++ b/sys/pc98/boot/Makefile.inc
@@ -1,7 +1,5 @@
-# $Id: Makefile.inc,v 1.3 1998/03/14 02:33:54 kato Exp $
+# $Id: Makefile.inc,v 1.2 1998/03/14 02:29:24 kato Exp $
-BINDIR?= /usr/mdec
-CFLAGS+= -aout
.if exists(${.CURDIR}/../../../../include)
CFLAGS+= -nostdinc -I${.CURDIR}/../../../../include
.endif
diff --git a/sys/pc98/boot/biosboot/Makefile b/sys/pc98/boot/biosboot/Makefile
index 3a2640c950d3..cef96e0f6c15 100644
--- a/sys/pc98/boot/biosboot/Makefile
+++ b/sys/pc98/boot/biosboot/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.21 1999/01/03 05:03:46 kato Exp $
+# $Id: Makefile,v 1.18 1998/05/28 13:46:04 kato Exp $
#
PROG= boot
@@ -6,6 +6,7 @@ PROG= boot
SRCS= start.S table.c boot2.S boot.c asm.S bios.S serial.S
SRCS+= probe_keyboard.c io.c disk.c sys.c
+BINDIR= /usr/mdec
BINMODE= 444
CFLAGS= -O2 -malign-functions=0 -malign-jumps=0 -malign-loops=0 \
-mno-486 \
@@ -15,8 +16,7 @@ CFLAGS+= ${CWARNFLAGS}
# By default, if a serial port is going to be used as console, use COM1
# (aka /dev/ttyd0).
-#BOOT_COMCONSOLE_PORT?=0x30
-BOOT_COMCONSOLE_PORT?=0x238
+BOOT_COMCONSOLE_PORT?=0x30
BOOT_COMCONSOLE_CLK?=16
BOOT_COMCONSOLE_MODE=0x0c
CFLAGS+= -DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \
@@ -24,8 +24,8 @@ CFLAGS+= -DCOMCONSOLE=${BOOT_COMCONSOLE_PORT} \
-DCOMCONSOLE_MODE=${BOOT_COMCONSOLE_MODE}
# feature not implemented
-BOOT_COMCONSOLE_SPEED?=9600
-CFLAGS+= -DCONSPEED=${BOOT_COMCONSOLE_SPEED}
+# BOOT_COMCONSOLE_SPEED?=9600
+# CFLAGS+= -DCONSPEED=${BOOT_COMCONSOLE_SPEED}
# Enable code to take the default boot string from a fixed location on the
# disk. See nextboot(8) and README.386BSD for more info.
@@ -64,8 +64,8 @@ BOOTSTACK= 0xFFF0
boot.strip: boot
cp -p boot boot.strip
- strip -aout boot.strip
- size -aout boot.strip
+ strip boot.strip
+ size boot.strip
boot.nohdr: boot.strip
dd if=boot.strip of=boot.nohdr ibs=32 skip=1 obs=1024b
@@ -86,11 +86,19 @@ boot2: boot.nohdr
all: boot1 boot2
install:
- ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
- boot1 boot2 ${DESTDIR}${BINDIR}/
+ ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE}\
+ boot1 ${DESTDIR}${BINDIR}/boot1
+ ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE}\
+ boot2 ${DESTDIR}${BINDIR}/boot2
+ for i in da fd wd od vn wfd ; do \
+ ( cd ${DESTDIR}${BINDIR} ; \
+ rm -f boot$${i} $${i}boot ; \
+ ln -s boot1 $${i}boot ; \
+ ln -s boot2 boot$${i} ; ) \
+ done
install-boothelp:
- ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${NOBINMODE} \
+ ${INSTALL} ${COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE}\
${.CURDIR}/boot.help ${DESTDIR}/
.include <bsd.kern.mk>
diff --git a/sys/pc98/boot/biosboot/README.serial b/sys/pc98/boot/biosboot/README.serial
index bf47e6c4a470..5adbfa941233 100644
--- a/sys/pc98/boot/biosboot/README.serial
+++ b/sys/pc98/boot/biosboot/README.serial
@@ -105,7 +105,7 @@ To boot FreeBSD in serial console mode, you must do the following:
higher priority console). This replaces the COMCONSOLE option.
Example:
- device sio0 at isa? port "IO_COM1" tty flags 0x10 irq 4
+ device sio0 at isa? port "IO_COM1" tty flags 0x10 irq 4 vector siointr
If the flags were not set, you need to run UserConfig (on a different
console) or recompile the kernel.
@@ -185,7 +185,7 @@ CAVEATS:
`flags' for the serial port you want to use. For example, if you
want to make COM2 the console:
- device sio1 at isa? port "IO_COM2" tty flags 0x10 irq 3
+ device sio1 at isa? port "IO_COM2" tty flags 0x10 irq 3 vector siointr
The console flags for the other serial ports should not be set.
o Recompile both the boot blocks and the kernel.
@@ -193,4 +193,4 @@ CAVEATS:
from the new kernel.
-$Id: README.serial,v 1.5 1998/04/07 15:33:47 kato Exp $
+$Id: README.serial,v 1.4 1997/06/09 13:44:03 kato Exp $
diff --git a/sys/pc98/boot/biosboot/serial.S b/sys/pc98/boot/biosboot/serial.S
index 2cc22465fe79..ebf1c5e9c0c9 100644
--- a/sys/pc98/boot/biosboot/serial.S
+++ b/sys/pc98/boot/biosboot/serial.S
@@ -24,7 +24,7 @@
* the rights to redistribute these changes.
*
* from: Mach, Revision 2.2 92/04/04 11:34:26 rpd
- * $Id: serial.S,v 1.7 1998/01/02 09:29:15 kato Exp $
+ * $Id: serial.S,v 1.6 1997/07/14 12:34:01 kato Exp $
*/
/*
@@ -65,16 +65,17 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*/
-#if COMCONSOLE == 0x238
-#include "../../../i386/boot/biosboot/serial.S"
-#else
/*
* modified for PC-98 by KATO T. of Nagoya University
*/
.file "serial.S"
+#ifdef PC98
+#include <pc98/pc98/sioreg.h>
+#else
#include <i386/isa/sioreg.h>
+#endif
#include "asm.h"
.text
@@ -198,4 +199,3 @@ ENTRY(init_serial)
outb %al, %dx
ret
-#endif
diff --git a/sys/pc98/boot/kzipboot/Makefile b/sys/pc98/boot/kzipboot/Makefile
index beb70a5e56cc..f97824c40ed5 100644
--- a/sys/pc98/boot/kzipboot/Makefile
+++ b/sys/pc98/boot/kzipboot/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.6 1998/05/28 13:48:40 kato Exp $
+# $Id: Makefile,v 1.5 1998/03/07 15:48:11 kato Exp $
PROG= kztail.o kzhead.o
BINMODE = 444 # target is a relocatable object
@@ -22,9 +22,9 @@ CFLAGS+= -DKZIP -DCOMCONSOLE=0x30
CFLAGS+= -DPC98
kztail.o: ${OBJS_KZTAIL}
- $(LD) -aout -r -x -o kztail.o $(OBJS_KZTAIL)
+ $(LD) -r -x -o kztail.o $(OBJS_KZTAIL)
kzhead.o: ${OBJS_KZHEAD}
- $(LD) -aout -r -x -o kzhead.o $(OBJS_KZHEAD)
+ $(LD) -r -x -o kzhead.o $(OBJS_KZHEAD)
.include <bsd.prog.mk>
diff --git a/sys/pc98/boot/kzipboot/malloc.c b/sys/pc98/boot/kzipboot/malloc.c
index 052e5e357dbb..cf51be721a51 100644
--- a/sys/pc98/boot/kzipboot/malloc.c
+++ b/sys/pc98/boot/kzipboot/malloc.c
@@ -36,8 +36,9 @@
extern unsigned char *storage;
void *
-kzipmalloc(nbytes)
+malloc(nbytes, junk1, junk2) /* junk? not used */
size_t nbytes;
+ int junk1, junk2;
{
unsigned char *p = storage;
storage += nbytes;
@@ -50,7 +51,8 @@ kzipmalloc(nbytes)
}
void
-kzipfree(cp)
+free(cp, junk) /* junk not used */
void *cp;
+ int junk;
{
}
diff --git a/sys/pc98/boot/netboot/Makefile b/sys/pc98/boot/netboot/Makefile
index dad72fc3b15d..37bfd672afab 100644
--- a/sys/pc98/boot/netboot/Makefile
+++ b/sys/pc98/boot/netboot/Makefile
@@ -36,6 +36,7 @@ PROG= nb8390.com nb8390.rom
# Order is very important on the SRCS line for this prog
SRCS= start2.S main.c misc.c bootmenu.c rpc.c
+BINDIR= /usr/mdec
BINMODE= 555
CFLAGS= -O2 -DNFS -DROMSIZE=${ROMSIZE} -DRELOC=${RELOCADDR} -DASK_BOOT
CFLAGS+= -DPC98
@@ -47,12 +48,10 @@ CFLAGS+= -DPC98
NS8390= -DINCLUDE_EGY -DNE_BASE=0xd0
CLEANFILES+= netboot.com
CLEANFILES+= makerom start2.ro 3c509.o ns8390.o
-ROMLDFLAGS= ${LDFLAGS} -aout -N -T ${RELOCADDR} -e _start -nostdlib
+ROMLDFLAGS= ${LDFLAGS} -N -T ${RELOCADDR} -e _start -nostdlib
NOSHARED= YES
NOMAN=
-SIZE= size -aout
STRIP=
-STRIPCMD= strip -aout
ROMSIZE=16384
RELOCADDR=0x90000
@@ -73,27 +72,27 @@ makerom: makerom.c
nb8390.rom: makerom start2.ro ${SRCS:N*.h:R:S/$/.o/g} ns8390.o
${LD} ${ROMLDFLAGS} -o ${.TARGET} ${OBJS:S/start2.o/start2.ro/} ns8390.o
- ${STRIPCMD} ${.TARGET}
- ${SIZE} ${.TARGET}
+ strip ${.TARGET}
+ size ${.TARGET}
${.OBJDIR}/makerom ${.TARGET}
nb3c509.rom: makerom start2.ro ${SRCS:N*.h:R:S/$/.o/g} 3c509.o
${LD} ${ROMLDFLAGS} -o ${.TARGET} ${OBJS:S/start2.o/start2.ro/} 3c509.o
- ${STRIPCMD} ${.TARGET}
- ${SIZE} ${.TARGET}
+ strip ${.TARGET}
+ size ${.TARGET}
${.OBJDIR}/makerom ${.TARGET}
nb8390.com: makerom start2.ro ${SRCS:N*.h:R:S/$/.o/g} ns8390.o
${LD} ${ROMLDFLAGS} -o ${.TARGET}.tmp ${OBJS} ns8390.o
- ${STRIPCMD} ${.TARGET}.tmp
- ${SIZE} ${.TARGET}.tmp
+ strip ${.TARGET}.tmp
+ size ${.TARGET}.tmp
dd ibs=32 skip=1 if=${.TARGET}.tmp of=${.TARGET}
rm -f ${.TARGET}.tmp
nb3c509.com: start2.o ${SRCS:N*.h:R:S/$/.o/g} 3c509.o
${LD} ${ROMLDFLAGS} -o ${.TARGET}.tmp ${OBJS} 3c509.o
- ${STRIPCMD} ${.TARGET}.tmp
- ${SIZE} ${.TARGET}.tmp
+ strip ${.TARGET}.tmp
+ size ${.TARGET}.tmp
dd ibs=32 skip=1 if=${.TARGET}.tmp of=${.TARGET}
rm -f ${.TARGET}.tmp
diff --git a/sys/pc98/boot/rawboot/Makefile b/sys/pc98/boot/rawboot/Makefile
index 7aafe0de65fd..b549f42f07d8 100644
--- a/sys/pc98/boot/rawboot/Makefile
+++ b/sys/pc98/boot/rawboot/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.11 1998/03/30 12:24:12 kato Exp $
+# $Id: Makefile,v 1.10 1998/03/14 02:30:01 kato Exp $
#
PROG= boot
@@ -9,6 +9,7 @@ SRCS+= probe_keyboard.c io.c disk.c sys.c
.PATH: ${.CURDIR}/../biosboot
+BINDIR= /usr/mdec
BINMODE= 444
CFLAGS= -O2 -malign-functions=0 -malign-jumps=0 -malign-loops=0 \
-DPC98 \
@@ -68,8 +69,8 @@ BOOTSTACK= 0xFFF0
boot.strip: boot
cp -p boot boot.strip
- strip -aout boot.strip
- size -aout boot.strip
+ strip boot.strip
+ size boot.strip
boot.nohdr: boot.strip
dd if=boot.strip of=boot.nohdr ibs=32 skip=1 obs=1024b
diff --git a/sys/pc98/conf/GENERIC98 b/sys/pc98/conf/GENERIC98
index 87d05b6cdad8..90ae50c81a55 100644
--- a/sys/pc98/conf/GENERIC98
+++ b/sys/pc98/conf/GENERIC98
@@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
-# $Id: GENERIC98,v 1.62 1999/01/16 13:20:42 kato Exp $
+# $Id: GENERIC98,v 1.49 1998/10/11 15:00:24 kato Exp $
# GENERIC98 -- Generic PC98 machine with WD/SCSI disks
@@ -41,7 +41,7 @@ options SCSI_DELAY=15000 #Be pessimistic about Joe SCSI device
options EPSON_BOUNCEDMA #use bounce buufer for 15-16M
#options EPSON_MEMWIN #EPSON memory window support
options UCONSOLE #Allow users to grab the console
-#options "LINE30"
+options "LINE30"
options FAILSAFE #Be conservative
options USERCONFIG #boot -c editor
options VISUAL_USERCONFIG #visual boot -c editor
@@ -58,26 +58,18 @@ options COM_MULTIPORT
config kernel root on wd0
-# To make an SMP kernel, the next two are needed
-#options SMP # Symmetric MultiProcessor Kernel
-#options APIC_IO # Symmetric (APIC) I/O
-# Optionally these may need tweaked, (defaults shown):
-#options NCPU=2 # number of CPUs
-#options NBUS=4 # number of busses
-#options NAPIC=1 # number of IO APICs
-#options NINTR=24 # number of INTs
-
controller isa0
controller pci0
-controller fdc0 at isa? port "IO_FD1" bio irq 11 drq 2
+controller fdc0 at isa? port "IO_FD1" bio irq 11 drq 2 vector fdintr
disk fd0 at fdc0 drive 0
disk fd1 at fdc0 drive 1
disk fd2 at fdc0 drive 2
disk fd3 at fdc0 drive 3
+tape ft0 at fdc0 drive 4
# options "CMD640" # work around CMD640 chip deficiency
-controller wdc0 at isa? port "IO_WD1" bio irq 9
+controller wdc0 at isa? port "IO_WD1" bio irq 9 vector wdintr
disk wd0 at wdc0 drive 0
#disk wd1 at wdc0 drive 1
#disk wd2 at wdc0 drive 2
@@ -85,11 +77,12 @@ disk wd0 at wdc0 drive 0
options ATAPI # Enable ATAPI support for IDE bus
options ATAPI_STATIC #Don't do it as an LKM
-device acd0 #IDE CD-ROM
+device wcd0 #IDE CD-ROM
-# A single entry for any of these controllers (ncr, ahb, ahc) is
+# A single entry for any of these controllers (ncr, ahb, ahc) is sufficient
# for any number of installed devices.
controller ncr0
+#controller amd0
controller ahc0
controller isp0
@@ -100,19 +93,19 @@ controller isp0
options BS_TARG_SAFEMODE
# PC-9801-92
-#controller bs0 at isa? port IO_SCSI bio irq 5 drq 3 flags 0
+controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0 vector bsintr
# SC-98
-# controller bs0 at isa? port IO_SCSI bio irq 5 drq 3 flags 0x10000
+# controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x10000 vector bsintr
# HA-55BS2 and later
-#controller bs0 at isa? port IO_SCSI bio irq 5 drq 3 flags 0x20000
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x20000 vector bsintr
# ELECOM type
-#controller bs0 at isa? port IO_SCSI bio irq 5 drq 3 flags 0x30000
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x30000 vector bsintr
# SMIT
-#controller bs0 at isa? port IO_SCSI bio irq 5 drq 3 iomem 0xdd000 iosiz 0x1000 flags 0x40000
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 iomem 0xdd000 iosiz 0x1000 flags 0x40000 vector bsintr
# Logitec LHA-20x
-#controller bs0 at isa? port IO_SCSI bio irq 5 drq 3 flags 0x50000
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x50000 vector bsintr
-#controller aic0 at isa? port 0x1840 bio irq 5 flags 0x10000
+#controller aic0 at isa? port 0x1840 bio irq 5 flags 0x10000 vector aicintr
controller scbus0
@@ -126,17 +119,11 @@ device cd0 #Only need one of these, the code dynamically grows
controller matcd0 at isa? port? bio
-# keyboard driver
-device pckbd0 at isa? port IO_KBD tty irq 1
-#options KBD_INSTALL_CDEV
-
-device gdc0 at isa?
-
-#pseudo-device splash
+# syscons is the default console driver, resembling an SCO console
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+#options XSERVER # support for X server
-device sc0 at isa? tty
-
-device npx0 at isa? port IO_NPX irq 8
+device npx0 at isa? port "IO_NPX" irq 8 vector npxintr
#
# Laptop support (see LINT for more options)
@@ -148,36 +135,12 @@ device apm0 at isa? disable flags 0x31 # Advanced Power Management
#device pcic0 at card?
#device pcic1 at card?
-#
-# Serial Interface
-#
-# COM1
-device sio0 at isa? port "IO_COM1" tty irq 4
-# COM2 (2nd CCU)
-device sio1 at isa? port 0x238 tty irq 5 flags 0x12000000
-# PC-9861K, PC-9801-101, MDC-926Rs
-#device sio1 at isa? port "IO_COM2" tty irq 5 flags 0x01000000
-#device sio2 at isa? port "IO_COM3" tty irq 6 flags 0x02000000
-# PC-9801-120 (PnP off)
-#device sio1 at isa? port 0x8b0 tty irq 5 flags 0x11000000
-# MC-16550II, MC-RS98
-#device sio1 at isa? port 0xd2 tty irq 5 flags 0x14000101
-#device sio2 at isa? port 0x8d2 tty flags 0x14000101
-# RSB-2000, RSB-3000, B98-02
-#device sio1 at isa? port 0xb0 tty flags 0x15000101
-#device sio2 at isa? port 0xb1 tty flags 0x15000101
-# RSB-384
-#device sio1 at isa? port 0xb0 tty flags 0x16000000
-#device sio2 at isa? port 0xb1 tty flags 0x16000000
-# RSA-98III
-#device sio1 at isa? port 0x50e0 tty irq 5 flags 0x18000101
-#device sio2 at isa? port 0x51e0 tty flags 0x18000101
-# ESP98
-#options COM_ESP
-#device sio1 at isa? port 0x18b0 tty irq 5 flags 0x19000000
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port 0xd2 tty irq 5 flags 0x101 vector siointr
+device sio2 at isa? port 0x8d2 tty flags 0x101 vector siointr
-device lpt0 at isa? port IO_LPT tty
-device mse0 at isa? port IO_MSE tty irq 13
+device lpt0 at isa? port "IO_LPT" tty
+device mse0 at isa? port "IO_MSE" tty irq 13 vector mseintr
# Order is important here due to intrusive probes, do *not* alphabetize
# this list of network interfaces until the probes have been fixed.
@@ -185,14 +148,9 @@ device mse0 at isa? port IO_MSE tty irq 13
# revision 1.20 of this file.
device de0
device fxp0
-device mx0
-device pn0
-device rl0
device tl0
device tx0
-device vr0
device vx0
-device wb0
#
# DP8390 NIC
@@ -210,30 +168,30 @@ device wb0
# fe0: RE1000/1000Plus
# fe1: C-NET(98)P2/C-NET(9N)E
#
-device ed0 at isa? port 0x00d0 net irq 6
-device ed5 at isa? port 0x00d0 net irq 6 iomem 0xd0000 iosiz 16384 flags 0x600000
-device ed1 at isa? port 0x00d8 net irq 6 flags 0x200000
-device ed3 at isa? port 0x00d0 net irq 6 flags 0x400000
-device ed4 at isa? port 0x56d0 net irq 5 flags 0x500000
-device ed2 at isa? port 0x00d8 net irq 6 flags 0x300000
-device ed7 at isa? port 0x00d0 net irq 6 flags 0x900000
-device ed6 at isa? port 0x0770 net irq 6 flags 0x800000
-device ed9 at isa? port 0x03d0 net irq 6 flags 0xb00000
-device ed8 at isa? port 0xa3d0 net irq 6 iomem 0xd0000 iosiz 16384 flags 0xa00000
+device ed0 at isa? port 0x00d0 net irq 6 vector edintr
+device ed1 at isa? port 0x00d8 net irq 6 flags 0x200000 vector edintr
+device ed2 at isa? port 0x00d8 net irq 6 flags 0x300000 vector edintr
+device ed3 at isa? port 0x00d0 net irq 6 flags 0x400000 vector edintr
+device ed4 at isa? port 0x56d0 net irq 5 flags 0x500000 vector edintr
+device ed5 at isa? port 0x00d0 net irq 6 iomem 0xd0000 iosiz 16384 flags 0x600000 vector edintr
+device ed6 at isa? port 0x0770 net irq 6 flags 0x800000 vector edintr
+device ed7 at isa? port 0x00d0 net irq 6 flags 0x900000 vector edintr
+device ed8 at isa? port 0xa3d0 net irq 6 iomem 0xd0000 iosiz 16384 flags 0xa00000 vector edintr
+device ed9 at isa? port 0x03d0 net irq 6 flags 0xb00000 vector edintr
-device ep0 at isa? port 0x40d0 net irq 3
-device fe0 at isa? port 0x00d0 net irq 3
-device fe1 at isa? port 0x73d0 net irq 5
-device lnc0 at isa? port 0x03d0 net irq 6
-device zp0 at isa? port 0x00d0 net irq 10 iomem 0xe0000
+device ep0 at isa? port 0x40d0 net irq 3 vector epintr
+device fe0 at isa? port 0x00d0 net irq 3 vector feintr
+device fe1 at isa? port 0x73d0 net irq 5 vector feintr
+device lnc0 at isa? port 0x03d0 net irq 6 vector lncintr
+device zp0 at isa? port 0x00d0 net irq 10 iomem 0xe0000 vector zpintr
#controller snd0
-#device sb0 at isa? port 0x20d2 irq 10 conflicts drq 3
+#device sb0 at isa? port 0x20d2 irq 10 conflicts drq 3 vector sbintr
#device sbxvi0 at isa? drq 3
#device sbmidi0 at isa? port 0x80d2
#device opl0 at isa? port 0x28d2
-#device pcm0 at isa? port 0xa460 irq 12
-#device mss0 at isa? port 0xf40 irq 12 drq 1
+#device pcm0 at isa? port 0xa460 irq 12 vector pcmintr
+#device mss0 at isa? port 0xf40 irq 12 drq 1 vector adintr
pseudo-device loop
pseudo-device ether
@@ -248,8 +206,3 @@ pseudo-device gzip # Exec gzipped a.out's
# the costs of each syscall.
options KTRACE #kernel tracing
-# The `bpfilter' pseudo-device enables the Berkeley Packet Filter. Be
-# aware of the legal and administrative consequences of enabling this
-# option. The number of devices determines the maximum number of
-# simultaneous BPF clients programs runnable.
-#pseudo-device bpfilter 4 #Berkeley packet filter
diff --git a/sys/pc98/conf/GENERICupgrade b/sys/pc98/conf/GENERICupgrade
new file mode 100644
index 000000000000..f07a434b2e7b
--- /dev/null
+++ b/sys/pc98/conf/GENERICupgrade
@@ -0,0 +1,204 @@
+#
+# GENERICupgrade (a copy of GENERIC98)
+#
+# This config file is used by the aout->elf transition build on systems
+# not running a 3.0-CURRENT kernel. Unless a kernel is built and installed
+# as part of the upgrade, the system will be hosed by the installation
+# of the 3.0 binaries and subsequent reboot. If the transition build is
+# being perfomed on a machine for which this config file is inappropriate,
+# it should be replaced with a suitable one prior to performing the upgrade.
+#
+# $Id: GENERICupgrade,v 1.3 1998/09/22 16:10:40 kato Exp $
+#
+
+# GENERIC98 -- Generic PC98 machine with WD/SCSI disks
+
+machine "pc98"
+cpu "I386_CPU"
+cpu "I486_CPU"
+cpu "I586_CPU"
+cpu "I686_CPU"
+ident "GENERIC98"
+maxusers 32
+
+options "PC98" #PC98
+options MATH_EMULATE #Support for x87 emulation
+options INET #InterNETworking
+options FFS #Berkeley Fast Filesystem
+options NFS #Network Filesystem
+options MSDOSFS #MSDOS Filesystem
+options "CD9660" #ISO 9660 Filesystem
+options "CD9660_ROOT" #CD-ROM usable as root device
+options FFS_ROOT #FFS usable as root device [keep this!]
+options NFS_ROOT #NFS usable as root device
+options PROCFS #Process filesystem
+options "COMPAT_43" #Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=15 #Be pessimistic about Joe SCSI device
+options EPSON_BOUNCEDMA #use bounce buufer for 15-16M
+#options EPSON_MEMWIN #EPSON memory window support
+options UCONSOLE #Allow users to grab the console
+options "LINE30"
+options FAILSAFE #Be conservative
+options USERCONFIG #boot -c editor
+options VISUAL_USERCONFIG #visual boot -c editor
+
+options SYSVSHM
+options SYSVSEM
+options SYSVMSG
+
+options COM_MULTIPORT
+
+#
+# IBM-PC HDD support
+#options COMPAT_ATDISK
+
+config kernel root on wd0
+
+controller isa0
+controller pci0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 11 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+disk fd1 at fdc0 drive 1
+disk fd2 at fdc0 drive 2
+disk fd3 at fdc0 drive 3
+tape ft0 at fdc0 drive 4
+
+# options "CMD640" # work around CMD640 chip deficiency
+controller wdc0 at isa? port "IO_WD1" bio irq 9 vector wdintr
+disk wd0 at wdc0 drive 0
+#disk wd1 at wdc0 drive 1
+#disk wd2 at wdc0 drive 2
+#disk wd3 at wdc0 drive 3
+
+options ATAPI # Enable ATAPI support for IDE bus
+options ATAPI_STATIC #Don't do it as an LKM
+device wcd0 #IDE CD-ROM
+
+# A single entry for any of these controllers (ncr, ahb, ahc) is sufficient
+# for any number of installed devices.
+controller ncr0
+#controller amd0
+controller ahc0
+controller isp0
+
+#
+# WD33C93 SCSI card (55/92 like board)
+#
+
+options BS_TARG_SAFEMODE
+
+# PC-9801-92
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0 vector bsintr
+# SC-98
+# controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x10000 vector bsintr
+# HA-55BS2 and later
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x20000 vector bsintr
+# ELECOM type
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x30000 vector bsintr
+# SMIT
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 iomem 0xdd000 iosiz 0x1000 flags 0x40000 vector bsintr
+# Logitec LHA-20x
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x50000 vector bsintr
+
+#controller aic0 at isa? port 0x1840 bio irq 5 flags 0x10000 vector aicintr
+
+controller scbus0
+
+device da0
+
+device sa0
+
+device pass0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+controller matcd0 at isa? port? bio
+
+# syscons is the default console driver, resembling an SCO console
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+#options XSERVER # support for X server
+
+device npx0 at isa? port "IO_NPX" irq 8 vector npxintr
+
+#
+# Laptop support (see LINT for more options)
+#
+device apm0 at isa? disable flags 0x31 # Advanced Power Management
+
+# PCCARD (PCMCIA) support
+#controller card0
+#device pcic0 at card?
+#device pcic1 at card?
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port 0xd2 tty irq 5 flags 0x101 vector siointr
+device sio2 at isa? port 0x8d2 tty flags 0x101 vector siointr
+
+device lpt0 at isa? port "IO_LPT" tty
+device mse0 at isa? port "IO_MSE" tty irq 13 vector mseintr
+
+# Order is important here due to intrusive probes, do *not* alphabetize
+# this list of network interfaces until the probes have been fixed.
+# Right now it appears that the ie0 must be probed before ep0. See
+# revision 1.20 of this file.
+device de0
+device fxp0
+device tl0
+device tx0
+device vx0
+
+#
+# DP8390 NIC
+#
+# ed0: generic driver
+# ed1: LANEED LD-BDN
+# ed2: EGY-98
+# ed3: LGY-98
+# ed4: ICM-IF-2766/EN-2298-T
+# ed5: SIC-98
+# ed6: PC-9801-108
+# ed7: LA-98
+# ed8: C-NET(98)
+# ed9: C-NET(98)E/L
+# fe0: RE1000/1000Plus
+# fe1: C-NET(98)P2/C-NET(9N)E
+#
+device ed0 at isa? port 0x00d0 net irq 6 vector edintr
+device ed1 at isa? port 0x00d8 net irq 6 flags 0x200000 vector edintr
+device ed2 at isa? port 0x00d8 net irq 6 flags 0x300000 vector edintr
+device ed3 at isa? port 0x00d0 net irq 6 flags 0x400000 vector edintr
+device ed4 at isa? port 0x56d0 net irq 5 flags 0x500000 vector edintr
+device ed5 at isa? port 0x00d0 net irq 6 iomem 0xd0000 iosiz 16384 flags 0x600000 vector edintr
+device ed6 at isa? port 0x0770 net irq 6 flags 0x800000 vector edintr
+device ed7 at isa? port 0x00d0 net irq 6 flags 0x900000 vector edintr
+device ed8 at isa? port 0xa3d0 net irq 6 iomem 0xd0000 iosiz 16384 flags 0xa00000 vector edintr
+device ed9 at isa? port 0x03d0 net irq 6 flags 0xb00000 vector edintr
+
+device ep0 at isa? port 0x40d0 net irq 3 vector epintr
+device fe0 at isa? port 0x00d0 net irq 3 vector feintr
+device fe1 at isa? port 0x73d0 net irq 5 vector feintr
+device lnc0 at isa? port 0x03d0 net irq 6 vector lncintr
+device zp0 at isa? port 0x00d0 net irq 10 iomem 0xe0000 vector zpintr
+
+#controller snd0
+#device sb0 at isa? port 0x20d2 irq 10 conflicts drq 3 vector sbintr
+#device sbxvi0 at isa? drq 3
+#device sbmidi0 at isa? port 0x80d2
+#device opl0 at isa? port 0x28d2
+#device pcm0 at isa? port 0xa460 irq 12 vector pcmintr
+#device mss0 at isa? port 0xf40 irq 12 drq 1 vector adintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device sl 1
+pseudo-device ppp 1
+pseudo-device tun 1
+pseudo-device pty 16
+pseudo-device gzip # Exec gzipped a.out's
+
+# KTRACE enables the system-call tracing facility ktrace(2).
+# This adds 4 KB bloat to your kernel, and slightly increases
+# the costs of each syscall.
+options KTRACE #kernel tracing
+
diff --git a/sys/pc98/conf/Makefile.pc98 b/sys/pc98/conf/Makefile.pc98
index 2af781934392..f6ba1b258a01 100644
--- a/sys/pc98/conf/Makefile.pc98
+++ b/sys/pc98/conf/Makefile.pc98
@@ -3,7 +3,7 @@
# Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.pc98,v 1.51 1999/01/18 11:00:29 kato Exp $
+# $Id: Makefile.pc98,v 1.41 1998/10/05 08:57:17 kato Exp $
#
# Makefile for FreeBSD
#
@@ -19,9 +19,9 @@
#
# Which version of config(8) is required.
-%VERSREQ= 300009
+%VERSREQ= 300007
-KERNFORMAT?= elf
+KERNFORMAT?= aout
#STD8X16FONT?= iso
@@ -77,8 +77,8 @@ DRIVER_C_C= ${CC} -c ${CFLAGS} ${PROF} $<
DRIVER_S= ${CC} -c -x ${ASM_CFLAGS} $<
PROFILE_C= ${CC} -c ${CFLAGS} $<
-GEN_CFILES= ${I386}/i386/genassym.c
-# setdef0.c and setdef1.c are intentionally
+GEN_CFILES= ${I386}/i386/genassym.c ${I386}/i386/gensetdefs.c
+# ${I386}/i386/setdef0.c and ${I386}/i386/setdef1.c are intentionally
# omitted from SYSTEM_CFILES. They include setdefs.h, a header which
# is generated from all of ${OBJS}. We don't want to have to compile
# everything just to do a make depend.
@@ -89,7 +89,14 @@ SYSTEM_DEP= Makefile symbols.exclude symbols.sort ${SYSTEM_OBJS}
SYMORDER_EXCLUDE=-x symbols.exclude
.endif
SYSTEM_LD_HEAD= @echo loading ${.TARGET}; rm -f ${.TARGET}
-.if ${KERNFORMAT} == aout || ${KERNFORMAT} == aoutkld
+.if ${KERNFORMAT} == aout
+SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} ioconf.o param.o config.o
+SYSTEM_LD= @${LD} -aout -Bstatic -Z -T ${LOAD_ADDRESS} -o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
+SYSTEM_LD_TAIL= @echo rearranging symbols; \
+ symorder -m ${SYMORDER_EXCLUDE} symbols.sort ${.TARGET}; \
+ size -aout ${.TARGET} ; chmod 755 ${.TARGET}
+.endif
+.if ${KERNFORMAT} == aoutkld
SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} ioconf.o param.o config.o
SYSTEM_LD= @${LD} -aout -Bforcedynamic -Z -T ${LOAD_ADDRESS} -o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
SYSTEM_LD_TAIL= @echo rearranging symbols; \
@@ -97,8 +104,9 @@ SYSTEM_LD_TAIL= @echo rearranging symbols; \
size -aout ${.TARGET} ; chmod 755 ${.TARGET}
.endif
.if ${KERNFORMAT} == elf
+# kld compatable export of symbols.
SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} ioconf.o param.o config.o \
- setdef1.o hack.So
+ setdef1.o hack.so
SYSTEM_LD= @${LD} -elf -Bdynamic -T $S/i386/conf/kernel.script \
-export-dynamic -dynamic-linker /red/herring \
-o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
@@ -120,14 +128,9 @@ SYSTEM_DEP+= $S/i386/conf/kernel.script
%CLEAN
-.if !exists(.depend)
-${SYSTEM_OBJS}: ${BEFORE_DEPEND:M*.h}
-.endif
-
clean:
- rm -f *.o *.so *.So *.ko *.s eddep errs genassym gensetdefs \
- kernel linterrs makelinks param.c setdef[01].c setdefs.h \
- symbols.exclude symbols.sort tags \
+ rm -f *.o *.so *.ko *.s eddep errs genassym gensetdefs kernel linterrs \
+ makelinks param.c setdefs.h symbols.exclude symbols.sort tags \
vers.c vnode_if.c vnode_if.h ${CLEAN}
#lint: /tmp param.c
@@ -151,21 +154,26 @@ locore.o: ${I386}/i386/locore.s assym.s
# This is a hack. BFD "optimizes" away dynamic mode if there are no
# dynamic references. We could probably do a '-Bforcedynamic' mode like
# in the a.out ld. For now, this works.
-hack.So: Makefile
+hack.so: Makefile
touch hack.c
- ${CC} -elf -shared -nostdlib hack.c -o hack.So
+ ${CC} -elf -shared -nostdlib hack.c -o hack.so
rm -f hack.c
.endif
-setdef0.o: setdef0.c setdefs.h
+setdef0.o: ${I386}/i386/setdef0.c setdefs.h
${NORMAL_C}
-setdef1.o: setdef1.c setdefs.h
+setdef1.o: ${I386}/i386/setdef1.c setdefs.h
${NORMAL_C}
-setdef0.c setdef1.c setdefs.h: ${OBJS}
- @echo generating linker set emulation glue for ELF
- @gensetdefs ${OBJS}
+setdefs.h: gensetdefs ${OBJS}
+ ./gensetdefs ${OBJS} >setdefs.h
+
+gensetdefs: gensetdefs.o
+ ${CC} ${GEN_CFLAGS} gensetdefs.o -o ${.TARGET}
+
+gensetdefs.o: ${I386}/i386/gensetdefs.c
+ ${CC} -c ${GEN_CFLAGS} ${I386}/i386/gensetdefs.c
# this rule stops ./assym.s in .depend from causing problems
./assym.s: assym.s
@@ -180,7 +188,7 @@ genassym.o: ${I386}/i386/genassym.c
genassym: genassym.o
${CC} ${GEN_CFLAGS} genassym.o -o ${.TARGET}
-${SYSTEM_OBJS} genassym.o vers.o: opt_global.h
+${SYSTEM_OBJS} genassym.o gensetdefs.o vers.o: opt_global.h
# XXX this assumes that the options for NORMAL_C* and DRIVER_C* are identical.
depend: assym.s param.c vnode_if.h ${BEFORE_DEPEND}
@@ -211,16 +219,6 @@ install:
echo "You must first build your kernel before trying to install." ; \
exit 1 ; \
fi
-.if ${KERNFORMAT} == "elf" && !defined(FORCE)
- @if [ -f /kernel -a "`file /kernel 2>/dev/null | grep ELF`" = "" ]; then \
- echo "WARNING: You are about to install an ELF kernel for the first time!" ; \
- echo "Please be sure you have upgraded your bootblocks and/or /boot/loader so" ; \
- echo "that you can boot it. Old bootblocks WILL NOT WORK! Please read:" ; \
- echo "http://www.freebsd.org/~peter/elfday.html for information." ; \
- echo "If you are satisfied you can boot an ELF kernel, type: make -DFORCE install" ; \
- exit 1 ; \
- fi
-.endif
.if exists(${DESTDIR}/kernel)
chflags noschg ${DESTDIR}/kernel
mv ${DESTDIR}/kernel ${DESTDIR}/kernel.old
diff --git a/sys/pc98/conf/SMP-GENERIC98 b/sys/pc98/conf/SMP-GENERIC98
new file mode 100644
index 000000000000..6b08d04497a9
--- /dev/null
+++ b/sys/pc98/conf/SMP-GENERIC98
@@ -0,0 +1,230 @@
+#
+# GENERIC -- Generic machine with WD/AHx/NCR/BTx family disks
+#
+# For more information read the handbook part System Administration ->
+# Configuring the FreeBSD Kernel -> The Configuration File.
+# The handbook is available in /usr/share/doc/handbook or online as
+# latest version from the FreeBSD World Wide Web server
+# <URL:http://www.FreeBSD.ORG/>
+#
+# An exhaustive list of options and more detailed explanations of the
+# device lines is present in the ./LINT configuration file. If you are
+# in doubt as to the purpose or necessity of a line, check first in LINT.
+#
+# $Id: SMP-GENERIC98,v 1.4 1998/09/19 13:36:13 kato Exp $
+
+# GENERIC98 -- Generic PC98 machine with WD/SCSI disks
+
+machine "pc98"
+# SMP does NOT support 386/486 CPUs.
+#cpu "I386_CPU"
+#cpu "I486_CPU"
+cpu "I586_CPU"
+cpu "I686_CPU"
+ident "SMP-GENERIC98"
+maxusers 32
+
+# Create a SMP capable kernel (mandatory options):
+options SMP # Symmetric MultiProcessor Kernel
+options APIC_IO # Symmetric (APIC) I/O
+
+# Optional, these are the defaults:
+#options NCPU=2 # number of CPUs
+#options NBUS=4 # number of busses
+#options NAPIC=1 # number of IO APICs
+#options NINTR=24 # number of INTs
+
+options "PC98" #PC98
+# SMP shouldn't need x87 emulation, disable by default.
+#options MATH_EMULATE #Support for x87 emulation
+options INET #InterNETworking
+options FFS #Berkeley Fast Filesystem
+options NFS #Network Filesystem
+options MSDOSFS #MSDOS Filesystem
+options "CD9660" #ISO 9660 Filesystem
+options "CD9660_ROOT" #CD-ROM usable as root device
+options FFS_ROOT #FFS usable as root device [keep this!]
+options NFS_ROOT #NFS usable as root device
+options PROCFS #Process filesystem
+options "COMPAT_43" #Compatible with BSD 4.3 [KEEP THIS!]
+options SCSI_DELAY=15000 #Be pessimistic about Joe SCSI device
+options UCONSOLE #Allow users to grab the console
+options "LINE30"
+options FAILSAFE #Be conservative
+options USERCONFIG #boot -c editor
+options VISUAL_USERCONFIG #visual boot -c editor
+
+options SYSVSHM
+options SYSVSEM
+options SYSVMSG
+
+options COM_MULTIPORT
+
+#
+# IBM-PC HDD support
+#options COMPAT_ATDISK
+#
+# FreeBSD(98)-current is a *TEST VERSION*.
+# It is highly recomended to compile with following options, and to
+# record the panic messages and the result of trace command brefore
+# reporting a problem.
+options DDB
+options DIAGNOSTIC
+
+config kernel root on wd0
+
+controller isa0
+controller pci0
+
+controller fdc0 at isa? port "IO_FD1" bio irq 11 drq 2 vector fdintr
+disk fd0 at fdc0 drive 0
+disk fd1 at fdc0 drive 1
+disk fd2 at fdc0 drive 2
+disk fd3 at fdc0 drive 3
+# Unless you know very well what you're doing, leave ft0 at drive 2, or
+# remove the line entirely if you don't need it. Trying to configure
+# it on another unit might cause surprises, see PR kern/7176.
+tape ft0 at fdc0 drive 4
+
+# options "CMD640" # work around CMD640 chip deficiency
+controller wdc0 at isa? port "IO_WD1" bio irq 9 vector wdintr
+disk wd0 at wdc0 drive 0
+#disk wd1 at wdc0 drive 1
+#disk wd2 at wdc0 drive 2
+#disk wd3 at wdc0 drive 3
+
+options ATAPI # Enable ATAPI support for IDE bus
+options ATAPI_STATIC #Don't do it as an LKM
+device wcd0 #IDE CD-ROM
+
+# A single entry for any of these controllers (ncr, ahb, ahc) is sufficient
+# for any number of installed devices.
+controller ncr0
+#controller amd0
+controller ahc0
+controller isp0
+
+
+#
+# SMP does not support bs driver: see /sys/i386/isa/bs/bsif.h
+#
+# WD33C93 SCSI card (55/92 like board)
+#
+
+options BS_TARG_SAFEMODE
+
+# PC-9801-92
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0 vector bsintr
+# SC-98
+# controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x10000 vector bsintr
+# HA-55BS2 and later
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x20000 vector bsintr
+# ELECOM type
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x30000 vector bsintr
+# SMIT
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 iomem 0xdd000 iosiz 0x1000 flags 0x40000 vector bsintr
+# Logitec LHA-20x
+#controller bs0 at isa? port "IO_SCSI" bio irq 5 drq 3 flags 0x50000 vector bsintr
+
+controller aic0 at isa? port 0x1840 bio irq 5 flags 0x10000 vector aicintr
+
+controller scbus0
+
+device da0
+
+device sa0
+
+device pass0
+
+device cd0 #Only need one of these, the code dynamically grows
+
+controller matcd0 at isa? port? bio
+
+# syscons is the default console driver, resembling an SCO console
+device sc0 at isa? port "IO_KBD" tty irq 1 vector scintr
+#options XSERVER # support for X server
+
+device npx0 at isa? port "IO_NPX" irq 8 vector npxintr
+
+#
+# Laptop support (see LINT for more options)
+#
+device apm0 at isa? disable flags 0x31 # Advanced Power Management
+
+# PCCARD (PCMCIA) support
+#controller card0
+#device pcic0 at card?
+#device pcic1 at card?
+
+device sio0 at isa? port "IO_COM1" tty irq 4 vector siointr
+device sio1 at isa? port 0xd2 tty irq 5 flags 0x101 vector siointr
+device sio2 at isa? port 0x8d2 tty flags 0x101 vector siointr
+
+device lpt0 at isa? port "IO_LPT" tty
+device mse0 at isa? port "IO_MSE" tty irq 13 vector mseintr
+
+# Order is important here due to intrusive probes, do *not* alphabetize
+# this list of network interfaces until the probes have been fixed.
+# Right now it appears that the ie0 must be probed before ep0. See
+# revision 1.20 of this file.
+device de0
+device fxp0
+device tl0
+device tx0
+device vx0
+device xl0
+
+#
+# DP8390 NIC
+#
+# ed0: generic driver
+# ed1: LANEED LD-BDN
+# ed2: EGY-98
+# ed3: LGY-98
+# ed4: ICM-IF-2766/EN-2298-T
+# ed5: SIC-98
+# ed6: PC-9801-108
+# ed7: LA-98
+# ed8: C-NET(98)
+# ed9: C-NET(98)E/L
+#
+device ed0 at isa? port 0x00d0 net irq 6 vector edintr
+device ed1 at isa? port 0x00d8 net irq 6 flags 0x200000 vector edintr
+device ed2 at isa? port 0x00d8 net irq 6 flags 0x300000 vector edintr
+device ed3 at isa? port 0x00d0 net irq 6 flags 0x400000 vector edintr
+device ed4 at isa? port 0x56d0 net irq 5 flags 0x500000 vector edintr
+device ed5 at isa? port 0x00d0 net irq 6 iomem 0xd0000 iosiz 16384 flags 0x600000 vector edintr
+device ed6 at isa? port 0x0770 net irq 6 flags 0x800000 vector edintr
+device ed7 at isa? port 0x00d0 net irq 6 flags 0x900000 vector edintr
+device ed8 at isa? port 0x03d0 net irq 6 iomem 0xd0000 iosiz 16384 flags 0xa00000 vector edintr
+device ed9 at isa? port 0x03d0 net irq 6 flags 0xb00000 vector edintr
+
+device ep0 at isa? port 0x40d0 net irq 3 vector epintr
+device fe0 at isa? port 0x00d0 net irq 3 vector feintr
+device lnc0 at isa? port 0x03d0 net irq 6 vector lncintr
+device zp0 at isa? port 0x00d0 net irq 10 iomem 0xe0000 vector zpintr
+
+#controller snd0
+#device sb0 at isa? port 0x20d2 irq 10 conflicts drq 3 vector sbintr
+#device sbxvi0 at isa? drq 3
+#device sbmidi0 at isa? port 0x80d2
+#device opl0 at isa? port 0x28d2
+#device pcm0 at isa? port 0xa460 irq 12 vector pcmintr
+#device mss0 at isa? port 0xf40 irq 12 drq 1 vector adintr
+
+pseudo-device loop
+pseudo-device ether
+pseudo-device sl 1
+#pseudo-device ppp 1
+pseudo-device tun 1
+pseudo-device pty 16
+pseudo-device gzip # Exec gzipped a.out's
+
+# KTRACE enables the system-call tracing facility ktrace(2).
+# This adds 4 KB bloat to your kernel, and slightly increases
+# the costs of each syscall.
+options KTRACE #kernel tracing
+
+# This provides support for System V shared memory.
+#
+options SYSVSHM
diff --git a/sys/pc98/conf/devices.pc98 b/sys/pc98/conf/devices.pc98
index cc10d30cd991..8b2641f04642 100644
--- a/sys/pc98/conf/devices.pc98
+++ b/sys/pc98/conf/devices.pc98
@@ -1,6 +1,6 @@
# This file tells what major numbers the various possible swap devices have.
#
-# $Id: devices.pc98,v 1.6 1998/09/15 14:10:55 kato Exp $
+# $Id: devices.pc98,v 1.5 1998/02/18 12:33:34 kato Exp $
#
wd 0
wfd 1
@@ -13,5 +13,5 @@ mcd 7
vn 15
scd 16
pcd 17
-acd 19
+wcd 19
wst 24
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index 1a5d72d84f6a..7b2d2a07e48d 100644
--- a/sys/pc98/conf/files.pc98
+++ b/sys/pc98/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.80 1999/01/18 08:38:07 kato Exp $
+# $Id: files.pc98,v 1.71 1998/09/20 10:50:18 kato Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -26,11 +26,6 @@ font8x16.o optional std8x16font \
no-implicit-rule before-depend \
clean "${STD8X16FONT}-8x16 font8x16.c"
#
-dev/fb/fb.c optional fb device-driver
-dev/fb/fb.c optional gdc device-driver
-dev/fb/splash.c optional splash
-dev/kbd/kbd.c optional kbd device-driver
-dev/kbd/kbd.c optional pckbd device-driver
i386/apm/apm.c optional apm device-driver
i386/apm/apm_setup.s optional apm
i386/eisa/dpt_eisa.c optional eisa dpt device-driver
@@ -76,7 +71,7 @@ i386/i386/simplelock.s optional smp
i386/i386/support.s standard
i386/i386/swtch.s standard
i386/i386/sys_machdep.c standard
-i386/i386/trap.c standard
+pc98/i386/trap.c standard
pc98/i386/userconfig.c optional userconfig
i386/i386/vm_machdep.c standard
i386/i386/vm86.c optional vm86
@@ -109,6 +104,8 @@ i386/isa/adv_isa.c optional adv device-driver
i386/isa/aha_isa.c optional aha device-driver
#i386/isa/aic6360.c optional aic device-driver
i386/isa/aic_isa.c optional aic device-driver
+i386/isa/alog.c optional alog device-driver
+i386/isa/b004.c optional bqu device-driver
i386/isa/bt_isa.c optional bt device-driver
pc98/pc98/clock.c standard
i386/isa/cronyx.c optional cx device-driver
@@ -120,6 +117,7 @@ pc98/pc98/atcompat_diskslice.c optional compat_atdisk
i386/isa/elink.c optional ep device-driver
i386/isa/elink.c optional ie device-driver
pc98/pc98/fd.c optional fd device-driver
+i386/isa/ft.c optional ft device-driver
i386/isa/gpib.c optional gp device-driver
i386/isa/asc.c optional asc device-driver
i386/isa/gsc.c optional gsc device-driver
@@ -127,14 +125,14 @@ i386/isa/if_ar.c optional ar device-driver
i386/isa/if_cs.c optional cs device-driver
i386/isa/if_cx.c optional cx device-driver
pc98/pc98/if_ed.c optional ed device-driver
+i386/isa/if_eg.c optional eg device-driver
i386/isa/if_el.c optional el device-driver
i386/isa/if_ep.c optional ep device-driver
i386/isa/if_ex.c optional ex device-driver
-i386/isa/if_fe.c optional fe device-driver
+pc98/pc98/if_fe.c optional fe device-driver
i386/isa/if_ie.c optional ie device-driver
i386/isa/if_le.c optional le device-driver
i386/isa/if_lnc.c optional lnc device-driver
-i386/isa/if_rdp.c optional rdp device-driver
i386/isa/if_sr.c optional sr device-driver
i386/isa/if_wl.c optional wl device-driver
i386/isa/if_ze.c optional ze device-driver
@@ -145,25 +143,27 @@ i386/isa/intr_machdep.c standard
pc98/pc98/pc98.c optional isa device-driver
i386/isa/istallion.c optional stli device-driver
i386/isa/joy.c optional joy device-driver
-pc98/pc98/pc98kbd.c optional pckbd device-driver
+i386/isa/kbdio.c optional psm device-driver
+i386/isa/kbdio.c optional sc device-driver
+i386/isa/kbdio.c optional vt device-driver
i386/isa/loran.c optional loran device-driver
pc98/pc98/lpt.c optional lpt device-driver
i386/isa/labpc.c optional labpc device-driver
i386/isa/mcd.c optional mcd device-driver
pc98/pc98/mse.c optional mse device-driver
+#i386/isa/ncr5380.c optional nca device-driver
pc98/pc98/npx.c mandatory npx device-driver
-pc98/pc98/pc98gdc.c optional gdc device-driver
pc98/pc98/pcaudio.c optional pca device-driver
i386/isa/matcd/matcd.c optional matcd device-driver
i386/isa/pcibus.c optional pci device-driver
i386/isa/pcicx.c optional ze device-driver
i386/isa/pcicx.c optional zp device-driver
-#i386/isa/pcvt/pcvt_drv.c optional vt device-driver
-#i386/isa/pcvt/pcvt_ext.c optional vt device-driver
-#i386/isa/pcvt/pcvt_kbd.c optional vt device-driver
-#i386/isa/pcvt/pcvt_out.c optional vt device-driver
-#i386/isa/pcvt/pcvt_sup.c optional vt device-driver
-#i386/isa/pcvt/pcvt_vtf.c optional vt device-driver
+i386/isa/pcvt/pcvt_drv.c optional vt device-driver
+i386/isa/pcvt/pcvt_ext.c optional vt device-driver
+i386/isa/pcvt/pcvt_kbd.c optional vt device-driver
+i386/isa/pcvt/pcvt_out.c optional vt device-driver
+i386/isa/pcvt/pcvt_sup.c optional vt device-driver
+i386/isa/pcvt/pcvt_vtf.c optional vt device-driver
i386/isa/pnp.c optional pnp device-driver
i386/isa/prof_machdep.c optional profiling-routine
i386/isa/ppc.c optional ppc device-driver
@@ -173,15 +173,17 @@ i386/isa/random_machdep.c standard
i386/isa/rc.c optional rc device-driver
i386/isa/rp.c optional rp device-driver
i386/isa/scd.c optional scd device-driver
+#i386/isa/seagate.c optional sea device-driver
i386/isa/si.c optional si device-driver
i386/isa/si2_z280.c optional si device-driver
i386/isa/si3_t225.c optional si device-driver
pc98/pc98/sio.c optional sio device-driver
-i386/isa/snd/sound.c optional pcm device-driver
-i386/isa/snd/dmabuf.c optional pcm device-driver
-i386/isa/snd/ad1848.c optional pcm device-driver
-i386/isa/snd/sb_dsp.c optional pcm device-driver
-i386/isa/snd/clones.c optional pcm device-driver
+#i386/isa/snd/sound.c optional pcm device-driver
+#i386/isa/snd/dmabuf.c optional pcm device-driver
+#i386/isa/snd/ad1848.c optional pcm device-driver
+#i386/isa/snd/sb_dsp.c optional pcm device-driver
+#i386/isa/snd/clones.c optional pcm device-driver
+i386/isa/sound/pcm86.c optional pcm device-driver
i386/isa/sound/dev_table.c optional snd device-driver
i386/isa/sound/soundcard.c optional snd device-driver
i386/isa/sound/sound_switch.c optional snd device-driver
@@ -247,17 +249,20 @@ i386/isa/spigot.c optional spigot device-driver
pc98/pc98/spkr.c optional speaker device-driver
i386/isa/stallion.c optional stl device-driver
pc98/pc98/syscons.c optional sc device-driver
-pc98/pc98/scvidctl.c optional sc device-driver
+#i386/isa/scvidctl.c optional sc device-driver
#i386/isa/scvesactl.c optional sc device-driver
#i386/isa/videoio.c optional sc device-driver
#i386/isa/vesa.c optional sc device-driver
i386/isa/tw.c optional tw device-driver
+#i386/isa/ultra14f.c optional uha device-driver
pc98/pc98/wd.c optional wdc device-driver
pc98/pc98/wd.c optional wd device-driver
i386/isa/atapi.c optional atapi device-driver
i386/isa/atapi-cd.c optional acd device-driver
+i386/isa/wcd.c optional wcd device-driver
i386/isa/wfd.c optional wfd device-driver
i386/isa/wst.c optional wst device-driver
+i386/isa/wd7000.c optional wds device-driver
i386/isa/wt.c optional wt device-driver
i386/linux/imgact_linux.c optional compat_linux
i386/linux/linux_dummy.c optional compat_linux
@@ -273,30 +278,6 @@ i386/linux/linux_stats.c optional compat_linux
i386/linux/linux_sysent.c optional compat_linux
i386/linux/linux_sysvec.c optional compat_linux
i386/linux/linux_util.c optional compat_linux
-i4b/layer1/i4b_isic.c optional isic device-driver
-i4b/layer1/i4b_isic_isa.c optional isic device-driver
-i4b/layer1/i4b_isic_pnp.c optional isic device-driver
-i4b/layer1/i4b_isic_pci.c optional isic device-driver
-i4b/layer1/i4b_isic_pcmcia.c optional isic device-driver
-i4b/layer1/i4b_isac.c optional isic device-driver
-i4b/layer1/i4b_hscx.c optional isic device-driver
-i4b/layer1/i4b_l1.c optional isic device-driver
-i4b/layer1/i4b_l1fsm.c optional isic device-driver
-i4b/layer1/i4b_bchan.c optional isic device-driver
-i4b/layer1/i4b_tel_s08.c optional isic device-driver
-i4b/layer1/i4b_tel_s016.c optional isic device-driver
-i4b/layer1/i4b_tel_s0163.c optional isic device-driver
-i4b/layer1/i4b_tel_s0P.c optional isic device-driver
-i4b/layer1/i4b_ctx_s0P.c optional isic device-driver
-i4b/layer1/i4b_avm_a1.c optional isic device-driver
-i4b/layer1/i4b_avm_fritz_pcmcia.c optional isic device-driver
-i4b/layer1/i4b_usr_sti.c optional isic device-driver
-i4b/layer1/i4b_itk_ix1.c optional isic device-driver
-i4b/layer1/i4b_drn_ngo.c optional isic device-driver
-i4b/layer1/i4b_sws.c optional isic device-driver
-i4b/layer1/i4b_dynalink.c optional isic device-driver
-i4b/layer1/i4b_elsa_qs1i.c optional isic device-driver
-i4b/layer1/i4b_elsa_qs1p.c optional isic device-driver
libkern/bcd.c standard
libkern/divdi3.c standard
libkern/inet_ntoa.c standard
@@ -351,5 +332,4 @@ gnu/i386/fpemul/wm_sqrt.s optional gpl_math_emulate
gnu/i386/isa/dgb.c optional dgb device-driver
gnu/i386/isa/dgm.c optional dgm device-driver
gnu/i386/isa/sound/awe_wave.c optional awe device-driver
-pci/es1370.c optional pcm device-driver
#pci/ide_pci.c optional wd device-driver
diff --git a/sys/pc98/conf/majors.pc98 b/sys/pc98/conf/majors.pc98
index 90ffbefccbce..2dce44c1a47f 100644
--- a/sys/pc98/conf/majors.pc98
+++ b/sys/pc98/conf/majors.pc98
@@ -1,4 +1,4 @@
-$Id: majors.pc98,v 1.48 1999/01/16 11:36:28 kato Exp $
+$Id: majors.pc98,v 1.40 1998/09/15 14:10:56 kato Exp $
Hopefully, this list will one day be obsoleted by DEVFS, but for now
this is the current allocation of device major numbers.
@@ -32,7 +32,7 @@ blkdev name comments
16 scd Sony CDROM interface
17 matcd Matsushita/Panasonic/Creative(SB) CDROM interface
18 ata "device independent" ATA/IDE driver
-19 acdb ATAPI CDROM client of "ata"
+19 wcdb ATAPI CDROM client of "ata"
21 ccd concatenated disk
22 gd Geometry disk.
24 wstb ATAPI tape client of "ata"
@@ -40,9 +40,6 @@ blkdev name comments
26 sw VM internal swap device
27 myx Mylex RAID (ulf@alameda.net)
28 fla M-Systems DiskOnChip(r)
-29 id Intelligent Disk [Array] (md@doc.ic.ac.uk)
-100 ?? entries from 100-127 are reserved for local use
-127 ?? entries from 100-127 are reserved for local use
chrdev name comments
0 cn console
@@ -114,7 +111,7 @@ chrdev name comments
66 labpc National Instruments LabPC
67 meteor Matrox Meteor video capture
68 si Specialix SI/XIO (peter@freebsd.org)
-69 acd ATAPI CDROM client of "ata"
+69 wcd ATAPI CDROM client of "ata"
71 asc AmiScan driver
72 stl Stallion (cd1400 based) (gerg@stallion.oz.au)
73 ?? was qcam
@@ -128,9 +125,9 @@ chrdev name comments
81 rp RocketPort/Steve Gericke <steveg@comtrol.com>
82 ppi Generic Parallel I/O <Nicolas.Souchu@prism.uvsq.fr>
83 can CAN16-2 CAN-PC Interface
-84 dtfp Datum Time and Frequency processor (louie@UU.NET)
+84 ttxt Unitext teletext decoder (arg@arg1.demon.co.uk)
85 vesa VESA support device (j_mini@efn.org)
-86 alog Industrial Computer Source AIO8-P driver (deprecated)
+86 alog Industrial Computer Source AIO8-P driver
87 wfd ATAPI floppy client of "ata"
88 dpt DPT RAID Controller <shimon@i-connect.net>
89 pps Pulse-Per-Second timing interface
@@ -152,12 +149,3 @@ chrdev name comments
105 iic I2C bus generic i/o
106 smb System Management Bus generic i/o
107 3dfx 3Dfx driver (shocking@prth.pgs.com)
-108 usb Universal Serial Bus (nick.hibma@jrc.it)
-109 id Intelligent Disk [Array] (md@doc.ic.ac.uk)
-110 ses SCSI Environmental Services driver (mjacob@feral.com)
-111 ums USB Mouse (nick.hibma@jrc.it)
-112 kbd keyboard
-113 ulpt USB Printer (nick.hibma@jrc.it)
-114 ugen USB Generic device (nick.hibma@jrc.it)
-200 ?? entries from 200-255 are reserved for local use
-255 ?? entries from 200-255 are reserved for local use
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index 22c264c07e3a..d18cabcdd4f9 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,7 +1,5 @@
-# $Id: options.pc98,v 1.77 1999/01/04 08:09:15 kato Exp $
-
+# $Id: options.pc98,v 1.68 1998/09/28 08:23:26 kato Exp $
DISABLE_PSE
-IDE_DELAY
USER_LDT
MATH_EMULATE opt_math_emulate.h
GPL_MATH_EMULATE opt_math_emulate.h
@@ -26,13 +24,19 @@ BREAK_TO_DEBUGGER opt_comconsole.h
CONSPEED opt_comconsole.h
COM_ESP opt_sio.h
COM_MULTIPORT opt_sio.h
+DSI_SOFT_MODEM opt_sio.h
EXTRA_SIO opt_sio.h
I586_PMC_GUPROF opt_i586_guprof.h
WLCACHE opt_wavelan.h
WLDEBUG opt_wavelan.h
-# i386 SMP options
+# These two SMP options have dramatic implications all over the kernel
+SMP opt_global.h
APIC_IO opt_global.h
+
+# Standard SMP options
+NCPU opt_smp.h
+NBUS opt_smp.h
NAPIC opt_smp.h
NINTR opt_smp.h
@@ -56,7 +60,6 @@ CPU_UPGRADE_HW_CACHE opt_cpu.h
CPU_WT_ALLOC opt_cpu.h
CYRIX_CACHE_WORKS opt_cpu.h
CYRIX_CACHE_REALLY_WORKS opt_cpu.h
-NO_MEMORY_HOLE opt_cpu.h
# The CPU type affects the endian conversion functions all over the kernel.
I386_CPU opt_global.h
@@ -64,29 +67,27 @@ I486_CPU opt_global.h
I586_CPU opt_global.h
I686_CPU opt_global.h
+SC_SPLASH_SCREEN opt_syscons.h
MAXCONS opt_syscons.h
+SLOW_VGA opt_syscons.h
STD8X16FONT opt_syscons.h
SC_HISTORY_SIZE opt_syscons.h
SC_DISABLE_REBOOT opt_syscons.h
SC_MOUSE_CHAR opt_syscons.h
-
-FB_INSTALL_CDEV opt_fb.h
+SC_ALT_SEQACCESS opt_syscons.h
VESA opt_vesa.h
-GDC opt_gdc.h
-
PSM_HOOKAPM opt_psm.h
PSM_RESETAFTERSUSPEND opt_psm.h
PSM_DEBUG opt_psm.h
PCIC_RESUME_RESET opt_pcic.h
-KBD_INSTALL_CDEV opt_kbd.h
-KBD_MAXRETRY opt_kbd.h
-KBD_MAXWAIT opt_kbd.h
-KBD_RESETDELAY opt_kbd.h
-KBDIO_DEBUG opt_kbd.h
+KBD_RESETDELAY opt_kbdio.h
+KBD_MAXRETRY opt_kbdio.h
+KBD_MAXWAIT opt_kbdio.h
+KBDIO_DEBUG opt_kbdio.h
ATAPI opt_atapi.h
ATAPI_STATIC opt_atapi.h
@@ -95,13 +96,12 @@ CMD640 opt_wd.h
USERCONFIG opt_userconfig.h
VISUAL_USERCONFIG opt_userconfig.h
-INTRO_USERCONFIG opt_userconfig.h
+USERCONFIG_BOOT opt_userconfig.h
EISA_SLOTS opt_eisa.h
FDC_DEBUG opt_fdc.h
FDC_PRINT_BOGUS_CHIPTYPE opt_fdc.h
-FDC_YE opt_fdc.h
# pcvt(4) has a bunch of options
FAT_CURSOR opt_pcvt.h
@@ -125,42 +125,6 @@ GUS_IRQ opt_sound.h
# Video spigot
SPIGOT_UNSECURE opt_spigot.h
-# -------------------------------
-# isdn4bsd: passive ISA cards
-# -------------------------------
-TEL_S0_8 opt_i4b.h
-TEL_S0_16 opt_i4b.h
-TEL_S0_16_3 opt_i4b.h
-AVM_A1 opt_i4b.h
-USR_STI opt_i4b.h
-ITKIX1 opt_i4b.h
-# -------------------------------
-# isdn4bsd: passive ISA PnP cards
-# -------------------------------
-CRTX_S0_P opt_i4b.h
-DRN_NGO opt_i4b.h
-TEL_S0_16_3_P opt_i4b.h
-SEDLBAUER opt_i4b.h
-DYNALINK opt_i4b.h
-ELSA_QS1ISA opt_i4b.h
-# -------------------------------
-# isdn4bsd: passive PCI cards
-# -------------------------------
-ELSA_QS1PCI opt_i4b.h
-# -------------------------------
-# isdn4bsd: passive PCMCIA cards
-# -------------------------------
-AVM_A1_PCMCIA opt_i4b.h
-# -------------------------------
-# isdn4bsd: misc options
-# -------------------------------
-# temporary workaround for SMP machines
-I4B_SMP_WORKAROUND opt_i4b.h
-# enable VJ compression code for ipr i/f
-IPR_VJ opt_i4b.h
-# -------------------------------
-# EOF
-# -------------------------------
# bs driver options
SCSI_BOUNCE_SIZE opt_bs.h
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
index 91095587ab6e..7449379560cf 100644
--- a/sys/pc98/i386/machdep.c
+++ b/sys/pc98/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.104 1999/01/08 16:04:20 kato Exp $
+ * $Id: machdep.c,v 1.98 1998/10/09 12:36:25 kato Exp $
*/
#include "apm.h"
@@ -109,6 +109,9 @@
#include <net/netisr.h>
#endif
+#if NAPM > 0
+#include <machine/apm_bios.h>
+#endif
#include <machine/cpu.h>
#include <machine/reg.h>
#include <machine/clock.h>
@@ -423,12 +426,6 @@ again:
*/
{
vm_offset_t mb_map_size;
- int xclusters;
-
- /* Allow override of NMBCLUSTERS from the kernel environment */
- if (getenv_int("kern.ipc.nmbclusters", &xclusters) &&
- xclusters > nmbclusters)
- nmbclusters = xclusters;
mb_map_size = nmbufs * MSIZE + nmbclusters * MCLBYTES;
mb_map_size = roundup2(mb_map_size, max(MCLBYTES, PAGE_SIZE));
@@ -452,8 +449,14 @@ again:
}
#if defined(USERCONFIG)
- userconfig();
- cninit(); /* the preferred console may have changed */
+#if defined(USERCONFIG_BOOT)
+ if (1) {
+#else
+ if (boothowto & RB_CONFIG) {
+#endif
+ userconfig();
+ cninit(); /* the preferred console may have changed */
+ }
#endif
printf("avail memory = %d (%dK bytes)\n", ptoa(cnt.v_free_count),
@@ -545,11 +548,7 @@ sendsig(catcher, sig, mask, code)
* and the stack can not be grown. useracc will return FALSE
* if access is denied.
*/
-#ifdef VM_STACK
- if ((grow_stack (p, (int)fp) == FALSE) ||
-#else
if ((grow(p, (int)fp) == FALSE) ||
-#endif
(useracc((caddr_t)fp, sizeof(struct sigframe), B_WRITE) == FALSE)) {
/*
* Process has trashed its stack; give it an illegal
@@ -644,7 +643,7 @@ sendsig(catcher, sig, mask, code)
}
regs->tf_esp = (int)fp;
- regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
+ regs->tf_eip = (int)(((char *)PS_STRINGS) - *(p->p_sysent->sv_szsigcode));
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
@@ -808,6 +807,17 @@ cpu_halt(void)
}
/*
+ * Turn the power off.
+ */
+void
+cpu_power_down(void)
+{
+#if NAPM > 0
+ apm_power_off();
+#endif
+}
+
+/*
* Clear registers on exec
*/
void
@@ -1255,7 +1265,11 @@ init386(first)
setidt(11, &IDTVEC(missing), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(12, &IDTVEC(stk), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(13, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+#ifdef CPU_BUGGY_CYRIX
setidt(14, &IDTVEC(page), SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+#else
+ setidt(14, &IDTVEC(page), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
+#endif
setidt(15, &IDTVEC(rsvd), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(16, &IDTVEC(fpu), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(17, &IDTVEC(align), SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@@ -1680,7 +1694,7 @@ f00f_hack(void *unused) {
if (!has_f00f_bug)
return;
- printf("Intel Pentium detected, installing workaround for F00F bug\n");
+ printf("Intel Pentium F00F detected, installing workaround\n");
r_idt.rd_limit = sizeof(idt) - 1;
diff --git a/sys/pc98/i386/trap.c b/sys/pc98/i386/trap.c
new file mode 100644
index 000000000000..9ea5d8051d1f
--- /dev/null
+++ b/sys/pc98/i386/trap.c
@@ -0,0 +1,1159 @@
+/*-
+ * Copyright (C) 1994, David Greenman
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * the University of Utah, and William Jolitz.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)trap.c 7.4 (Berkeley) 5/13/91
+ * $Id: trap.c,v 1.50 1998/04/29 09:45:38 kato Exp $
+ */
+
+/*
+ * 386 Trap and System call handling
+ */
+
+#include "opt_cpu.h"
+#include "opt_ddb.h"
+#include "opt_ktrace.h"
+#include "opt_trap.h"
+#include "opt_vm86.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/pioctl.h>
+#include <sys/kernel.h>
+#include <sys/resourcevar.h>
+#include <sys/signalvar.h>
+#include <sys/syscall.h>
+#include <sys/sysent.h>
+#include <sys/uio.h>
+#include <sys/vmmeter.h>
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_prot.h>
+#include <sys/lock.h>
+#include <vm/pmap.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_page.h>
+#include <vm/vm_extern.h>
+
+#include <machine/cpu.h>
+#include <machine/ipl.h>
+#include <machine/md_var.h>
+#include <machine/pcb.h>
+#ifdef SMP
+#include <machine/smp.h>
+#endif
+#include <machine/tss.h>
+
+#include <i386/isa/intr_machdep.h>
+
+#ifdef POWERFAIL_NMI
+#include <sys/syslog.h>
+#include <machine/clock.h>
+#endif
+
+#ifdef VM86
+#include <machine/vm86.h>
+#endif
+
+#include "isa.h"
+#include "npx.h"
+
+extern struct i386tss common_tss;
+
+int (*pmath_emulate) __P((struct trapframe *));
+
+extern void trap __P((struct trapframe frame));
+extern int trapwrite __P((unsigned addr));
+extern void syscall __P((struct trapframe frame));
+
+#ifdef CPU_BUGGY_CYRIX
+static int trap_pfault __P((struct trapframe *, int, vm_offset_t));
+#else
+static int trap_pfault __P((struct trapframe *, int));
+#endif
+static void trap_fatal __P((struct trapframe *));
+void dblfault_handler __P((void));
+
+extern inthand_t IDTVEC(syscall);
+
+#define MAX_TRAP_MSG 28
+static char *trap_msg[] = {
+ "", /* 0 unused */
+ "privileged instruction fault", /* 1 T_PRIVINFLT */
+ "", /* 2 unused */
+ "breakpoint instruction fault", /* 3 T_BPTFLT */
+ "", /* 4 unused */
+ "", /* 5 unused */
+ "arithmetic trap", /* 6 T_ARITHTRAP */
+ "system forced exception", /* 7 T_ASTFLT */
+ "", /* 8 unused */
+ "general protection fault", /* 9 T_PROTFLT */
+ "trace trap", /* 10 T_TRCTRAP */
+ "", /* 11 unused */
+ "page fault", /* 12 T_PAGEFLT */
+ "", /* 13 unused */
+ "alignment fault", /* 14 T_ALIGNFLT */
+ "", /* 15 unused */
+ "", /* 16 unused */
+ "", /* 17 unused */
+ "integer divide fault", /* 18 T_DIVIDE */
+ "non-maskable interrupt trap", /* 19 T_NMI */
+ "overflow trap", /* 20 T_OFLOW */
+ "FPU bounds check fault", /* 21 T_BOUND */
+ "FPU device not available", /* 22 T_DNA */
+ "double fault", /* 23 T_DOUBLEFLT */
+ "FPU operand fetch fault", /* 24 T_FPOPFLT */
+ "invalid TSS fault", /* 25 T_TSSFLT */
+ "segment not present fault", /* 26 T_SEGNPFLT */
+ "stack fault", /* 27 T_STKFLT */
+ "machine check trap", /* 28 T_MCHK */
+};
+
+static __inline void userret __P((struct proc *p, struct trapframe *frame,
+ u_quad_t oticks));
+
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+extern struct gate_descriptor *t_idt;
+extern int has_f00f_bug;
+#endif
+
+static __inline void
+userret(p, frame, oticks)
+ struct proc *p;
+ struct trapframe *frame;
+ u_quad_t oticks;
+{
+ int sig, s;
+
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+
+#if 0
+ if (!want_resched &&
+ (p->p_priority <= p->p_usrpri) &&
+ (p->p_rtprio.type == RTP_PRIO_NORMAL)) {
+ int newpriority;
+ p->p_estcpu += 1;
+ newpriority = PUSER + p->p_estcpu / 4 + 2 * p->p_nice;
+ newpriority = min(newpriority, MAXPRI);
+ p->p_usrpri = newpriority;
+ }
+#endif
+
+ p->p_priority = p->p_usrpri;
+ if (want_resched) {
+ /*
+ * Since we are curproc, clock will normally just change
+ * our priority without moving us from one queue to another
+ * (since the running process is not on a queue.)
+ * If that happened after we setrunqueue ourselves but before we
+ * mi_switch()'ed, we might not be on the queue indicated by
+ * our priority.
+ */
+ s = splhigh();
+ setrunqueue(p);
+ p->p_stats->p_ru.ru_nivcsw++;
+ mi_switch();
+ splx(s);
+ while ((sig = CURSIG(p)) != 0)
+ postsig(sig);
+ }
+ /*
+ * Charge system time if profiling.
+ */
+ if (p->p_flag & P_PROFIL)
+ addupc_task(p, frame->tf_eip,
+ (u_int)(p->p_sticks - oticks) * psratio);
+
+ curpriority = p->p_priority;
+}
+
+/*
+ * Exception, fault, and trap interface to the FreeBSD kernel.
+ * This common code is called from assembly language IDT gate entry
+ * routines that prepare a suitable stack frame, and restore this
+ * frame after the exception has been processed.
+ */
+
+void
+trap(frame)
+ struct trapframe frame;
+{
+ struct proc *p = curproc;
+ u_quad_t sticks = 0;
+ int i = 0, ucode = 0, type, code;
+#ifdef DEBUG
+ u_long eva;
+#endif
+#ifdef CPU_BUGGY_CYRIX
+ vm_offset_t va;
+#endif
+
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+restart:
+#endif
+ type = frame.tf_trapno;
+ code = frame.tf_err;
+
+#ifdef CPU_BUGGY_CYRIX
+ /* XXX:
+ * CYRIX 486 CPU FIX.
+ * If you use cyrix cpu, you often encouter strange signal 11's?
+ * I think this is due to cyrix cpu bugs.
+ * In any way, the following trick is effective for the problem.
+ * As soon as possible, we must get the fault page address.
+ */
+ va = (vm_offset_t)(rcr2());
+ if( type == T_PAGEFLT && ( frame.tf_eflags & PSL_I ) )
+ asm("sti");
+#endif /* CPU_BUGGY_CYRIX */
+
+#ifdef VM86
+ if (in_vm86call) {
+ if (frame.tf_eflags & PSL_VM &&
+ (type == T_PROTFLT || type == T_STKFLT)) {
+ i = vm86_emulate((struct vm86frame *)&frame);
+ if (i != 0)
+ /*
+ * returns to original process
+ */
+ vm86_trap((struct vm86frame *)&frame);
+ return;
+ }
+ switch (type) {
+ /*
+ * these traps want either a process context, or
+ * assume a normal userspace trap.
+ */
+ case T_PROTFLT:
+ case T_SEGNPFLT:
+ trap_fatal(&frame);
+ return;
+ case T_TRCTRAP:
+ type = T_BPTFLT; /* kernel breakpoint */
+ /* FALL THROUGH */
+ }
+ goto kernel_trap; /* normal kernel trap handling */
+ }
+#endif
+
+ if ((ISPL(frame.tf_cs) == SEL_UPL) || (frame.tf_eflags & PSL_VM)) {
+ /* user trap */
+
+ sticks = p->p_sticks;
+ p->p_md.md_regs = &frame;
+
+ switch (type) {
+ case T_PRIVINFLT: /* privileged instruction fault */
+ ucode = type;
+ i = SIGILL;
+ break;
+
+ case T_BPTFLT: /* bpt instruction fault */
+ case T_TRCTRAP: /* trace trap */
+ frame.tf_eflags &= ~PSL_T;
+ i = SIGTRAP;
+ break;
+
+ case T_ARITHTRAP: /* arithmetic trap */
+ ucode = code;
+ i = SIGFPE;
+ break;
+
+ case T_ASTFLT: /* Allow process switch */
+ astoff();
+ cnt.v_soft++;
+ if (p->p_flag & P_OWEUPC) {
+ p->p_flag &= ~P_OWEUPC;
+ addupc_task(p, p->p_stats->p_prof.pr_addr,
+ p->p_stats->p_prof.pr_ticks);
+ }
+ goto out;
+
+ /*
+ * The following two traps can happen in
+ * vm86 mode, and, if so, we want to handle
+ * them specially.
+ */
+ case T_PROTFLT: /* general protection fault */
+ case T_STKFLT: /* stack fault */
+#ifdef VM86
+ if (frame.tf_eflags & PSL_VM) {
+ i = vm86_emulate((struct vm86frame *)&frame);
+ if (i == 0)
+ goto out;
+ break;
+ }
+#endif /* VM86 */
+ /* FALL THROUGH */
+
+ case T_SEGNPFLT: /* segment not present fault */
+ case T_TSSFLT: /* invalid TSS fault */
+ case T_DOUBLEFLT: /* double fault */
+ default:
+ ucode = code + BUS_SEGM_FAULT ;
+ i = SIGBUS;
+ break;
+
+ case T_PAGEFLT: /* page fault */
+#ifdef CPU_BUGGY_CYRIX
+ i = trap_pfault(&frame, TRUE, va);
+#else
+ i = trap_pfault(&frame, TRUE);
+#endif
+ if (i == -1)
+ return;
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+ if (i == -2)
+ goto restart;
+#endif
+ if (i == 0)
+ goto out;
+
+ ucode = T_PAGEFLT;
+ break;
+
+ case T_DIVIDE: /* integer divide fault */
+ ucode = FPE_INTDIV_TRAP;
+ i = SIGFPE;
+ break;
+
+#if NISA > 0
+ case T_NMI:
+#ifdef POWERFAIL_NMI
+ goto handle_powerfail;
+#else /* !POWERFAIL_NMI */
+#ifdef DDB
+ /* NMI can be hooked up to a pushbutton for debugging */
+ printf ("NMI ... going to debugger\n");
+ if (kdb_trap (type, 0, &frame))
+ return;
+#endif /* DDB */
+ /* machine/parity/power fail/"kitchen sink" faults */
+ if (isa_nmi(code) == 0) return;
+ panic("NMI indicates hardware failure");
+#endif /* POWERFAIL_NMI */
+#endif /* NISA > 0 */
+
+ case T_OFLOW: /* integer overflow fault */
+ ucode = FPE_INTOVF_TRAP;
+ i = SIGFPE;
+ break;
+
+ case T_BOUND: /* bounds check fault */
+ ucode = FPE_SUBRNG_TRAP;
+ i = SIGFPE;
+ break;
+
+ case T_DNA:
+#if NNPX > 0
+ /* if a transparent fault (due to context switch "late") */
+ if (npxdna())
+ return;
+#endif
+ if (!pmath_emulate) {
+ i = SIGFPE;
+ ucode = FPE_FPU_NP_TRAP;
+ break;
+ }
+ i = (*pmath_emulate)(&frame);
+ if (i == 0) {
+ if (!(frame.tf_eflags & PSL_T))
+ return;
+ frame.tf_eflags &= ~PSL_T;
+ i = SIGTRAP;
+ }
+ /* else ucode = emulator_only_knows() XXX */
+ break;
+
+ case T_FPOPFLT: /* FPU operand fetch fault */
+ ucode = T_FPOPFLT;
+ i = SIGILL;
+ break;
+ }
+ } else {
+#ifdef VM86
+kernel_trap:
+#endif
+ /* kernel trap */
+
+ switch (type) {
+ case T_PAGEFLT: /* page fault */
+#ifdef CPU_BUGGY_CYRIX
+ (void) trap_pfault(&frame, FALSE, va);
+#else
+ (void) trap_pfault(&frame, FALSE);
+#endif
+ return;
+
+ case T_DNA:
+#if NNPX > 0
+ /*
+ * The kernel is apparently using npx for copying.
+ * XXX this should be fatal unless the kernel has
+ * registered such use.
+ */
+ if (npxdna())
+ return;
+#endif
+ break;
+
+ case T_PROTFLT: /* general protection fault */
+ case T_SEGNPFLT: /* segment not present fault */
+ /*
+ * Invalid segment selectors and out of bounds
+ * %eip's and %esp's can be set up in user mode.
+ * This causes a fault in kernel mode when the
+ * kernel tries to return to user mode. We want
+ * to get this fault so that we can fix the
+ * problem here and not have to check all the
+ * selectors and pointers when the user changes
+ * them.
+ */
+#define MAYBE_DORETI_FAULT(where, whereto) \
+ do { \
+ if (frame.tf_eip == (int)where) { \
+ frame.tf_eip = (int)whereto; \
+ return; \
+ } \
+ } while (0)
+
+ if (intr_nesting_level == 0) {
+ /*
+ * Invalid %fs's and %gs's can be created using
+ * procfs or PT_SETREGS or by invalidating the
+ * underlying LDT entry. This causes a fault
+ * in kernel mode when the kernel attempts to
+ * switch contexts. Lose the bad context
+ * (XXX) so that we can continue, and generate
+ * a signal.
+ */
+ if (frame.tf_eip == (int)cpu_switch_load_fs) {
+ curpcb->pcb_fs = 0;
+ psignal(p, SIGBUS);
+ return;
+ }
+ if (frame.tf_eip == (int)cpu_switch_load_gs) {
+ curpcb->pcb_gs = 0;
+ psignal(p, SIGBUS);
+ return;
+ }
+ MAYBE_DORETI_FAULT(doreti_iret,
+ doreti_iret_fault);
+ MAYBE_DORETI_FAULT(doreti_popl_ds,
+ doreti_popl_ds_fault);
+ MAYBE_DORETI_FAULT(doreti_popl_es,
+ doreti_popl_es_fault);
+ if (curpcb && curpcb->pcb_onfault) {
+ frame.tf_eip = (int)curpcb->pcb_onfault;
+ return;
+ }
+ }
+ break;
+
+ case T_TSSFLT:
+ /*
+ * PSL_NT can be set in user mode and isn't cleared
+ * automatically when the kernel is entered. This
+ * causes a TSS fault when the kernel attempts to
+ * `iret' because the TSS link is uninitialized. We
+ * want to get this fault so that we can fix the
+ * problem here and not every time the kernel is
+ * entered.
+ */
+ if (frame.tf_eflags & PSL_NT) {
+ frame.tf_eflags &= ~PSL_NT;
+ return;
+ }
+ break;
+
+ case T_TRCTRAP: /* trace trap */
+ if (frame.tf_eip == (int)IDTVEC(syscall)) {
+ /*
+ * We've just entered system mode via the
+ * syscall lcall. Continue single stepping
+ * silently until the syscall handler has
+ * saved the flags.
+ */
+ return;
+ }
+ if (frame.tf_eip == (int)IDTVEC(syscall) + 1) {
+ /*
+ * The syscall handler has now saved the
+ * flags. Stop single stepping it.
+ */
+ frame.tf_eflags &= ~PSL_T;
+ return;
+ }
+ /*
+ * Fall through.
+ */
+ case T_BPTFLT:
+ /*
+ * If DDB is enabled, let it handle the debugger trap.
+ * Otherwise, debugger traps "can't happen".
+ */
+#ifdef DDB
+ if (kdb_trap (type, 0, &frame))
+ return;
+#endif
+ break;
+
+#if NISA > 0
+ case T_NMI:
+#ifdef POWERFAIL_NMI
+#ifndef TIMER_FREQ
+# define TIMER_FREQ 1193182
+#endif
+ handle_powerfail:
+ {
+ static unsigned lastalert = 0;
+
+ if(time_second - lastalert > 10)
+ {
+ log(LOG_WARNING, "NMI: power fail\n");
+ sysbeep(TIMER_FREQ/880, hz);
+ lastalert = time_second;
+ }
+ return;
+ }
+#else /* !POWERFAIL_NMI */
+#ifdef DDB
+ /* NMI can be hooked up to a pushbutton for debugging */
+ printf ("NMI ... going to debugger\n");
+ if (kdb_trap (type, 0, &frame))
+ return;
+#endif /* DDB */
+ /* machine/parity/power fail/"kitchen sink" faults */
+ if (isa_nmi(code) == 0) return;
+ /* FALL THROUGH */
+#endif /* POWERFAIL_NMI */
+#endif /* NISA > 0 */
+ }
+
+ trap_fatal(&frame);
+ return;
+ }
+
+ /* Translate fault for emulators (e.g. Linux) */
+ if (*p->p_sysent->sv_transtrap)
+ i = (*p->p_sysent->sv_transtrap)(i, type);
+
+ trapsignal(p, i, ucode);
+
+#ifdef DEBUG
+ eva = rcr2();
+ if (type <= MAX_TRAP_MSG) {
+ uprintf("fatal process exception: %s",
+ trap_msg[type]);
+ if ((type == T_PAGEFLT) || (type == T_PROTFLT))
+ uprintf(", fault VA = 0x%lx", eva);
+ uprintf("\n");
+ }
+#endif
+
+out:
+ userret(p, &frame, sticks);
+}
+
+#ifdef notyet
+/*
+ * This version doesn't allow a page fault to user space while
+ * in the kernel. The rest of the kernel needs to be made "safe"
+ * before this can be used. I think the only things remaining
+ * to be made safe are the iBCS2 code and the process tracing/
+ * debugging code.
+ */
+static int
+#ifdef CPU_BUGGY_CYRIX
+trap_pfault(frame, usermode,faultva)
+ struct trapframe *frame;
+ int usermode;
+ vm_offset_t faultva;
+#else
+trap_pfault(frame, usermode)
+ struct trapframe *frame;
+ int usermode;
+#endif
+{
+ vm_offset_t va;
+ struct vmspace *vm = NULL;
+ vm_map_t map = 0;
+ int rv = 0;
+ vm_prot_t ftype;
+ int eva;
+ struct proc *p = curproc;
+
+ if (frame->tf_err & PGEX_W)
+ ftype = VM_PROT_READ | VM_PROT_WRITE;
+ else
+ ftype = VM_PROT_READ;
+
+#ifdef CPU_BUGGY_CYRIX
+ eva = faultva;
+#else
+ eva = rcr2();
+#endif
+ va = trunc_page((vm_offset_t)eva);
+
+ if (va < VM_MIN_KERNEL_ADDRESS) {
+ vm_offset_t v;
+ vm_page_t mpte;
+
+ if (p == NULL ||
+ (!usermode && va < VM_MAXUSER_ADDRESS &&
+ (intr_nesting_level != 0 || curpcb == NULL ||
+ curpcb->pcb_onfault == NULL))) {
+ trap_fatal(frame);
+ return (-1);
+ }
+
+ /*
+ * This is a fault on non-kernel virtual memory.
+ * vm is initialized above to NULL. If curproc is NULL
+ * or curproc->p_vmspace is NULL the fault is fatal.
+ */
+ vm = p->p_vmspace;
+ if (vm == NULL)
+ goto nogo;
+
+ map = &vm->vm_map;
+
+ /*
+ * Keep swapout from messing with us during this
+ * critical time.
+ */
+ ++p->p_lock;
+
+ /*
+ * Grow the stack if necessary
+ */
+ if ((caddr_t)va > vm->vm_maxsaddr
+ && (caddr_t)va < (caddr_t)USRSTACK) {
+ if (!grow(p, va)) {
+ rv = KERN_FAILURE;
+ --p->p_lock;
+ goto nogo;
+ }
+ }
+
+ /* Fault in the user page: */
+ rv = vm_fault(map, va, ftype,
+ (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : 0);
+
+ --p->p_lock;
+ } else {
+ /*
+ * Don't allow user-mode faults in kernel address space.
+ */
+ if (usermode)
+ goto nogo;
+
+ /*
+ * Since we know that kernel virtual address addresses
+ * always have pte pages mapped, we just have to fault
+ * the page.
+ */
+ rv = vm_fault(kernel_map, va, ftype, FALSE);
+ }
+
+ if (rv == KERN_SUCCESS)
+ return (0);
+nogo:
+ if (!usermode) {
+ if (intr_nesting_level == 0 && curpcb && curpcb->pcb_onfault) {
+ frame->tf_eip = (int)curpcb->pcb_onfault;
+ return (0);
+ }
+ trap_fatal(frame);
+ return (-1);
+ }
+
+ /* kludge to pass faulting virtual address to sendsig */
+ frame->tf_err = eva;
+
+ return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
+}
+#endif
+
+int
+#ifdef CPU_BUGGY_CYRIX
+trap_pfault(frame, usermode,faultva)
+ struct trapframe *frame;
+ int usermode;
+ vm_offset_t faultva;
+#else
+trap_pfault(frame, usermode)
+ struct trapframe *frame;
+ int usermode;
+#endif
+{
+ vm_offset_t va;
+ struct vmspace *vm = NULL;
+ vm_map_t map = 0;
+ int rv = 0;
+ vm_prot_t ftype;
+ int eva;
+ struct proc *p = curproc;
+
+#ifdef CPU_BUGGY_CYRIX
+ eva = faultva;
+#else
+ eva = rcr2();
+#endif
+ va = trunc_page((vm_offset_t)eva);
+
+ if (va >= KERNBASE) {
+ /*
+ * Don't allow user-mode faults in kernel address space.
+ * An exception: if the faulting address is the invalid
+ * instruction entry in the IDT, then the Intel Pentium
+ * F00F bug workaround was triggered, and we need to
+ * treat it is as an illegal instruction, and not a page
+ * fault.
+ */
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
+ if ((eva == (unsigned int)&t_idt[6]) && has_f00f_bug) {
+ frame->tf_trapno = T_PRIVINFLT;
+ return -2;
+ }
+#endif
+ if (usermode)
+ goto nogo;
+
+ map = kernel_map;
+ } else {
+ /*
+ * This is a fault on non-kernel virtual memory.
+ * vm is initialized above to NULL. If curproc is NULL
+ * or curproc->p_vmspace is NULL the fault is fatal.
+ */
+ if (p != NULL)
+ vm = p->p_vmspace;
+
+ if (vm == NULL)
+ goto nogo;
+
+ map = &vm->vm_map;
+ }
+
+ if (frame->tf_err & PGEX_W)
+ ftype = VM_PROT_READ | VM_PROT_WRITE;
+ else
+ ftype = VM_PROT_READ;
+
+ if (map != kernel_map) {
+ /*
+ * Keep swapout from messing with us during this
+ * critical time.
+ */
+ ++p->p_lock;
+
+ /*
+ * Grow the stack if necessary
+ */
+ if ((caddr_t)va > vm->vm_maxsaddr
+ && (caddr_t)va < (caddr_t)USRSTACK) {
+ if (!grow(p, va)) {
+ rv = KERN_FAILURE;
+ --p->p_lock;
+ goto nogo;
+ }
+ }
+
+ /* Fault in the user page: */
+ rv = vm_fault(map, va, ftype,
+ (ftype & VM_PROT_WRITE) ? VM_FAULT_DIRTY : 0);
+
+ --p->p_lock;
+ } else {
+ /*
+ * Don't have to worry about process locking or stacks in the kernel.
+ */
+ rv = vm_fault(map, va, ftype, FALSE);
+ }
+
+ if (rv == KERN_SUCCESS)
+ return (0);
+nogo:
+ if (!usermode) {
+ if (intr_nesting_level == 0 && curpcb && curpcb->pcb_onfault) {
+ frame->tf_eip = (int)curpcb->pcb_onfault;
+ return (0);
+ }
+ trap_fatal(frame);
+ return (-1);
+ }
+
+ /* kludge to pass faulting virtual address to sendsig */
+ frame->tf_err = eva;
+
+ return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
+}
+
+static void
+trap_fatal(frame)
+ struct trapframe *frame;
+{
+ int code, type, eva, ss, esp;
+ struct soft_segment_descriptor softseg;
+
+ code = frame->tf_err;
+ type = frame->tf_trapno;
+ eva = rcr2();
+ sdtossd(&gdt[IDXSEL(frame->tf_cs & 0xffff)].sd, &softseg);
+
+ if (type <= MAX_TRAP_MSG)
+ printf("\n\nFatal trap %d: %s while in %s mode\n",
+ type, trap_msg[type],
+ frame->tf_eflags & PSL_VM ? "vm86" :
+ ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel");
+#ifdef SMP
+ /* three seperate prints in case of a trap on an unmapped page */
+ printf("mp_lock = %08x; ", mp_lock);
+ printf("cpuid = %d; ", cpuid);
+ printf("lapic.id = %08x\n", lapic.id);
+#endif
+ if (type == T_PAGEFLT) {
+ printf("fault virtual address = 0x%x\n", eva);
+ printf("fault code = %s %s, %s\n",
+ code & PGEX_U ? "user" : "supervisor",
+ code & PGEX_W ? "write" : "read",
+ code & PGEX_P ? "protection violation" : "page not present");
+ }
+ printf("instruction pointer = 0x%x:0x%x\n",
+ frame->tf_cs & 0xffff, frame->tf_eip);
+ if ((ISPL(frame->tf_cs) == SEL_UPL) || (frame->tf_eflags & PSL_VM)) {
+ ss = frame->tf_ss & 0xffff;
+ esp = frame->tf_esp;
+ } else {
+ ss = GSEL(GDATA_SEL, SEL_KPL);
+ esp = (int)&frame->tf_esp;
+ }
+ printf("stack pointer = 0x%x:0x%x\n", ss, esp);
+ printf("frame pointer = 0x%x:0x%x\n", ss, frame->tf_ebp);
+ printf("code segment = base 0x%x, limit 0x%x, type 0x%x\n",
+ softseg.ssd_base, softseg.ssd_limit, softseg.ssd_type);
+ printf(" = DPL %d, pres %d, def32 %d, gran %d\n",
+ softseg.ssd_dpl, softseg.ssd_p, softseg.ssd_def32,
+ softseg.ssd_gran);
+ printf("processor eflags = ");
+ if (frame->tf_eflags & PSL_T)
+ printf("trace trap, ");
+ if (frame->tf_eflags & PSL_I)
+ printf("interrupt enabled, ");
+ if (frame->tf_eflags & PSL_NT)
+ printf("nested task, ");
+ if (frame->tf_eflags & PSL_RF)
+ printf("resume, ");
+ if (frame->tf_eflags & PSL_VM)
+ printf("vm86, ");
+ printf("IOPL = %d\n", (frame->tf_eflags & PSL_IOPL) >> 12);
+ printf("current process = ");
+ if (curproc) {
+ printf("%lu (%s)\n",
+ (u_long)curproc->p_pid, curproc->p_comm ?
+ curproc->p_comm : "");
+ } else {
+ printf("Idle\n");
+ }
+ printf("interrupt mask = ");
+ if ((cpl & net_imask) == net_imask)
+ printf("net ");
+ if ((cpl & tty_imask) == tty_imask)
+ printf("tty ");
+ if ((cpl & bio_imask) == bio_imask)
+ printf("bio ");
+ if ((cpl & cam_imask) == cam_imask)
+ printf("cam ");
+ if (cpl == 0)
+ printf("none");
+#ifdef SMP
+/**
+ * XXX FIXME:
+ * we probably SHOULD have stopped the other CPUs before now!
+ * another CPU COULD have been touching cpl at this moment...
+ */
+ printf(" <- SMP: XXX");
+#endif
+ printf("\n");
+
+#ifdef KDB
+ if (kdb_trap(&psl))
+ return;
+#endif
+#ifdef DDB
+ if (kdb_trap (type, 0, frame))
+ return;
+#endif
+ printf("trap number = %d\n", type);
+ if (type <= MAX_TRAP_MSG)
+ panic(trap_msg[type]);
+ else
+ panic("unknown/reserved trap");
+}
+
+/*
+ * Double fault handler. Called when a fault occurs while writing
+ * a frame for a trap/exception onto the stack. This usually occurs
+ * when the stack overflows (such is the case with infinite recursion,
+ * for example).
+ *
+ * XXX Note that the current PTD gets replaced by IdlePTD when the
+ * task switch occurs. This means that the stack that was active at
+ * the time of the double fault is not available at <kstack> unless
+ * the machine was idle when the double fault occurred. The downside
+ * of this is that "trace <ebp>" in ddb won't work.
+ */
+void
+dblfault_handler()
+{
+ printf("\nFatal double fault:\n");
+ printf("eip = 0x%x\n", common_tss.tss_eip);
+ printf("esp = 0x%x\n", common_tss.tss_esp);
+ printf("ebp = 0x%x\n", common_tss.tss_ebp);
+#ifdef SMP
+ /* three seperate prints in case of a trap on an unmapped page */
+ printf("mp_lock = %08x; ", mp_lock);
+ printf("cpuid = %d; ", cpuid);
+ printf("lapic.id = %08x\n", lapic.id);
+#endif
+ panic("double fault");
+}
+
+/*
+ * Compensate for 386 brain damage (missing URKR).
+ * This is a little simpler than the pagefault handler in trap() because
+ * it the page tables have already been faulted in and high addresses
+ * are thrown out early for other reasons.
+ */
+int trapwrite(addr)
+ unsigned addr;
+{
+ struct proc *p;
+ vm_offset_t va;
+ struct vmspace *vm;
+ int rv;
+
+ va = trunc_page((vm_offset_t)addr);
+ /*
+ * XXX - MAX is END. Changed > to >= for temp. fix.
+ */
+ if (va >= VM_MAXUSER_ADDRESS)
+ return (1);
+
+ p = curproc;
+ vm = p->p_vmspace;
+
+ ++p->p_lock;
+
+ if ((caddr_t)va >= vm->vm_maxsaddr
+ && (caddr_t)va < (caddr_t)USRSTACK) {
+ if (!grow(p, va)) {
+ --p->p_lock;
+ return (1);
+ }
+ }
+
+ /*
+ * fault the data page
+ */
+ rv = vm_fault(&vm->vm_map, va, VM_PROT_READ|VM_PROT_WRITE, VM_FAULT_DIRTY);
+
+ --p->p_lock;
+
+ if (rv != KERN_SUCCESS)
+ return 1;
+
+ return (0);
+}
+
+/*
+ * System call request from POSIX system call gate interface to kernel.
+ * Like trap(), argument is call by reference.
+ */
+void
+syscall(frame)
+ struct trapframe frame;
+{
+ caddr_t params;
+ int i;
+ struct sysent *callp;
+ struct proc *p = curproc;
+ u_quad_t sticks;
+ int error;
+ int args[8];
+ u_int code;
+
+#ifdef DIAGNOSTIC
+ if (ISPL(frame.tf_cs) != SEL_UPL)
+ panic("syscall");
+#endif
+ sticks = p->p_sticks;
+ p->p_md.md_regs = &frame;
+ params = (caddr_t)frame.tf_esp + sizeof(int);
+ code = frame.tf_eax;
+ if (p->p_sysent->sv_prepsyscall) {
+ (*p->p_sysent->sv_prepsyscall)(&frame, args, &code, &params);
+ } else {
+ /*
+ * Need to check if this is a 32 bit or 64 bit syscall.
+ */
+ if (code == SYS_syscall) {
+ /*
+ * Code is first argument, followed by actual args.
+ */
+ code = fuword(params);
+ params += sizeof(int);
+ } else if (code == SYS___syscall) {
+ /*
+ * Like syscall, but code is a quad, so as to maintain
+ * quad alignment for the rest of the arguments.
+ */
+ code = fuword(params);
+ params += sizeof(quad_t);
+ }
+ }
+
+ if (p->p_sysent->sv_mask)
+ code &= p->p_sysent->sv_mask;
+
+ if (code >= p->p_sysent->sv_size)
+ callp = &p->p_sysent->sv_table[0];
+ else
+ callp = &p->p_sysent->sv_table[code];
+
+ if (params && (i = callp->sy_narg * sizeof(int)) &&
+ (error = copyin(params, (caddr_t)args, (u_int)i))) {
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSCALL))
+ ktrsyscall(p->p_tracep, code, callp->sy_narg, args);
+#endif
+ goto bad;
+ }
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSCALL))
+ ktrsyscall(p->p_tracep, code, callp->sy_narg, args);
+#endif
+ p->p_retval[0] = 0;
+ p->p_retval[1] = frame.tf_edx;
+
+ STOPEVENT(p, S_SCE, callp->sy_narg);
+
+ error = (*callp->sy_call)(p, args);
+
+ switch (error) {
+
+ case 0:
+ /*
+ * Reinitialize proc pointer `p' as it may be different
+ * if this is a child returning from fork syscall.
+ */
+ p = curproc;
+ frame.tf_eax = p->p_retval[0];
+ frame.tf_edx = p->p_retval[1];
+ frame.tf_eflags &= ~PSL_C;
+ break;
+
+ case ERESTART:
+ /*
+ * Reconstruct pc, assuming lcall $X,y is 7 bytes,
+ * int 0x80 is 2 bytes. We saved this in tf_err.
+ */
+ frame.tf_eip -= frame.tf_err;
+ break;
+
+ case EJUSTRETURN:
+ break;
+
+ default:
+bad:
+ if (p->p_sysent->sv_errsize)
+ if (error >= p->p_sysent->sv_errsize)
+ error = -1; /* XXX */
+ else
+ error = p->p_sysent->sv_errtbl[error];
+ frame.tf_eax = error;
+ frame.tf_eflags |= PSL_C;
+ break;
+ }
+
+ if ((frame.tf_eflags & PSL_T) && !(frame.tf_eflags & PSL_VM)) {
+ /* Traced syscall. */
+ frame.tf_eflags &= ~PSL_T;
+ trapsignal(p, SIGTRAP, 0);
+ }
+
+ userret(p, &frame, sticks);
+
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p->p_tracep, code, error, p->p_retval[0]);
+#endif
+
+ /*
+ * This works because errno is findable through the
+ * register set. If we ever support an emulation where this
+ * is not the case, this code will need to be revisited.
+ */
+ STOPEVENT(p, S_SCX, code);
+
+}
+
+/*
+ * Simplified back end of syscall(), used when returning from fork()
+ * directly into user mode.
+ */
+void
+fork_return(p, frame)
+ struct proc *p;
+ struct trapframe frame;
+{
+ frame.tf_eax = 0; /* Child returns zero */
+ frame.tf_eflags &= ~PSL_C; /* success */
+ frame.tf_edx = 1;
+
+ userret(p, &frame, 0);
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_SYSRET))
+ ktrsysret(p->p_tracep, SYS_fork, 0, 0);
+#endif
+}
diff --git a/sys/pc98/i386/userconfig.c b/sys/pc98/i386/userconfig.c
index 30fccbc4da75..d291653b8419 100644
--- a/sys/pc98/i386/userconfig.c
+++ b/sys/pc98/i386/userconfig.c
@@ -46,7 +46,7 @@
** (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: userconfig.c,v 1.64 1999/01/16 11:39:08 kato Exp $
+ ** $Id: userconfig.c,v 1.56 1998/10/08 12:09:38 kato Exp $
**/
/**
@@ -117,8 +117,6 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/reboot.h>
-#include <sys/linker.h>
-#include <sys/sysctl.h>
#include <machine/cons.h>
#include <machine/md_var.h>
@@ -137,156 +135,36 @@ static MALLOC_DEFINE(M_DEVL, "isa_devlist", "isa_device lists in userconfig()");
static struct isa_device *isa_devlist; /* list read by dset to extract changes */
+#ifdef USERCONFIG_BOOT
+char userconfig_from_boot[512] = "";
static int userconfig_boot_parsing; /* set if we are reading from the boot instructions */
-#define putchar(x) cnputc(x)
-
static int
-sysctl_machdep_uc_devlist SYSCTL_HANDLER_ARGS
+getchar(void)
{
- struct isa_device *id;
- int error=0;
- char name[8];
+ static char *next = userconfig_from_boot;
- if(!req->oldptr) {
- /* Only sizing */
- id=isa_devlist;
- while(id) {
- error+=sizeof(struct isa_device)+8;
- id=id->id_next;
- }
- return(SYSCTL_OUT(req,0,error));
+ if (next == userconfig_from_boot) {
+ if (strncmp(next, "USERCONFIG\n", 11)) {
+ next++;
+ strcpy(next, "intro\n");
} else {
- /* Output the data. The buffer is filled with consecutive
- * struct isa_device and char buf[8], containing the name
- * (not guaranteed to end with '\0').
- */
- id=isa_devlist;
- while(id) {
- error=sysctl_handle_opaque(oidp,id,
- sizeof(struct isa_device),req);
- if(error) return(error);
- strncpy(name,id->id_driver->name,8);
- error=sysctl_handle_opaque(oidp,name,
- 8,req);
- if(error) return(error);
- id=id->id_next;
- }
- return(0);
- }
-}
-
-SYSCTL_PROC( _machdep, OID_AUTO, uc_devlist, CTLFLAG_RD,
- 0, 0, sysctl_machdep_uc_devlist, "A",
- "List of ISA devices changed in UserConfig");
-
-/*
-** Obtain command input.
-**
-** Initially, input is read from a possibly-loaded script.
-** At the end of the script, or if no script is supplied,
-** behaviour is determined by the RB_CONFIG (-c) flag. If
-** the flag is set, user input is read from the console; if
-** unset, the 'quit' command is invoked and userconfig
-** will exit.
-**
-** Note that quit commands encountered in the script will be
-** ignored if the RB_CONFIG flag is supplied.
-*/
-static int
-getchar(void)
-{
- static const char *asp;
- static int assize; /* use of int for -ve magic value */
- static int autocheck = 0;
- caddr_t autoentry, autoattr;
- int c = 0;
- static int intro = 0;
-
- /* Look for loaded userconfig script */
- if (autocheck == 0)
- {
- autocheck = 1;
- autoentry = preload_search_by_type("userconfig_script");
- if (autoentry != NULL)
- {
- /* We have one, get size and data */
- assize = 0;
- if ((autoattr = preload_search_info(autoentry, MODINFO_SIZE)) != NULL)
- assize = (size_t)*(u_int32_t *)autoattr;
- asp = NULL;
- if ((autoattr = preload_search_info(autoentry, MODINFO_ADDR)) != NULL)
- asp = *(const char **)autoattr;
- /* sanity check */
- if ((assize == 0) || (asp == NULL)) {
- assize = 0;
- asp = NULL;
- }
+ next += 11;
}
- }
-
- if (assize > 0)
- {
- /* Consume character from loaded userconfig script, display */
+ }
+ if (*next) {
userconfig_boot_parsing = 1;
- c = *asp;
- asp++;
- assize--;
-
- } else if (assize == 0) {
-
-#ifdef INTRO_USERCONFIG
- if (intro == 0)
- {
- /*
- * We don't want intro if we just executed a
- * script (userconfig_boot_parsing==1), otherwise
- * we would always block here waiting for user input.
- */
- intro = 1;
- if (userconfig_boot_parsing == 0)
- {
- /* userconfig_boot_parsing will be set to 1 on next pass,
- * which will allow using 'intro' in the middle of other
- * userconfig_script commands.
- */
- c = 'i';
- asp = "ntro\n";
- assize = strlen(asp);
- } else {
- userconfig_boot_parsing = 0;
- assize=-1;
- }
-#else
+ return (*next++);
+ } else {
userconfig_boot_parsing = 0;
- if (!(boothowto & RB_CONFIG))
- {
- /* don't want to drop to interpreter */
- c = 'q';
- asp = "uit\n";
- assize = strlen(asp);
-#endif
- userconfig_boot_parsing = 0;
- } else {
- /* Only display signon banner if we are about to go interactive */
- if (!intro)
- printf("\nFreeBSD Kernel Configuration Utility - Version 1.2\n"
- " Type \"help\" for help"
-#ifdef VISUAL_USERCONFIG
- " or \"visual\" to go to the visual\n"
- " configuration interface (requires MGA/VGA display or\n"
- " serial terminal capable of displaying ANSI graphics)"
-#endif
- ".\n");
- assize = -1;
- }
+ return cngetc();
}
- if (assize < 0) {
- /* No script, read from the keyboard */
- c = cngetc();
- }
- return(c);
}
+#else /* !USERCONFIG_BOOT */
+#define getchar() cngetc()
+#endif /* USERCONFIG_BOOT */
+
+#define putchar(x) cnputc(x)
#ifndef FALSE
#define FALSE (0)
@@ -403,16 +281,10 @@ static DEV_INFO device_info[] = {
{"vx", "3COM 3C590/3C595 Ethernet adapters", 0, CLS_NETWORK},
{"ze", "IBM/National Semiconductor PCMCIA Ethernet adapter",0, CLS_NETWORK},
{"zp", "3COM PCMCIA Etherlink III Ethernet adapter", 0, CLS_NETWORK},
-{"ax", "ASIC AX88140A ethernet adapter", FLG_FIXED, CLS_NETWORK},
{"de", "DEC DC21040 Ethernet adapter", FLG_FIXED, CLS_NETWORK},
{"fpa", "DEC DEFPA PCI FDDI adapter", FLG_FIXED, CLS_NETWORK},
-{"rl", "RealTek 8129/8139 ethernet adapter", FLG_FIXED, CLS_NETWORK},
-{"mx", "Macronix PMAC ethernet adapter", FLG_FIXED, CLS_NETWORK},
-{"pn", "Lite-On 82c168/82c169 PNIC adapter", FLG_FIXED, CLS_NETWORK},
-{"tl", "Texas Instruments ThunderLAN ethernet adapter", FLG_FIXED, CLS_NETWORK},
-{"vr", "VIA Rhine/Rhine II ethernet adapter", FLG_FIXED, CLS_NETWORK},
-{"wb", "Winbond W89C840F ethernet adapter", FLG_FIXED, CLS_NETWORK},
-{"xl", "3COM 3C90x PCI ethernet adapter", FLG_FIXED, CLS_NETWORK},
+{"tlc", "Texas Instruments ThunderLAN ethernet adapter", FLG_FIXED, CLS_NETWORK},
+{"xl", "3COM 3C90x PCI FDDI adapter", FLG_FIXED, CLS_NETWORK},
{"sio", "8250/16450/16550 Serial port", 0, CLS_COMMS},
{"cx", "Cronyx/Sigma multiport sync/async adapter",0, CLS_COMMS},
@@ -2081,17 +1953,15 @@ static void
helpscreen(void)
{
int topline = 0; /* where we are in the text */
- int c, delta = 1;
+ int line, c, delta = 1;
char prompt[80];
for (;;) /* loop until user quits */
{
- int line = 0;
-
/* display help text */
if (delta)
{
- clear(); /* remove everything else */
+ clear(); /* remove everything else */
for (line = topline;
(line < (topline + 24)) && (helptext[line]);
line++)
@@ -2531,7 +2401,7 @@ visuserconfig(void)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: userconfig.c,v 1.64 1999/01/16 11:39:08 kato Exp $
+ * $Id: userconfig.c,v 1.56 1998/10/08 12:09:38 kato Exp $
*/
#include "scbus.h"
@@ -2584,7 +2454,7 @@ static int set_device_enable(CmdParm *);
static int set_device_disable(CmdParm *);
static int quitfunc(CmdParm *);
static int helpfunc(CmdParm *);
-#if defined(INTRO_USERCONFIG)
+#if defined(USERCONFIG_BOOT)
static int introfunc(CmdParm *);
#endif
@@ -2622,12 +2492,10 @@ static CmdParm dev_parms[] = {
{ -1, {} },
};
-#if NPNP > 0
static CmdParm string_arg[] = {
{ PARM_STRING, {} },
{ -1, {} },
};
-#endif
#if NEISA > 0
static CmdParm int_arg[] = {
@@ -2647,7 +2515,7 @@ static Cmd CmdList[] = {
{ "ex", quitfunc, NULL }, /* exit (quit) */
{ "f", set_device_flags, int_parms }, /* flags dev mask */
{ "h", helpfunc, NULL }, /* help */
-#if defined(INTRO_USERCONFIG)
+#if defined(USERCONFIG_BOOT)
{ "intro", introfunc, NULL }, /* intro screen */
#endif
{ "iom", set_device_mem, addr_parms }, /* iomem dev addr */
@@ -2676,6 +2544,16 @@ userconfig(void)
int rval;
Cmd *cmd;
+ printf("\nFreeBSD Kernel Configuration Utility - Version 1.1\n"
+ " Type \"help\" for help"
+#ifdef VISUAL_USERCONFIG
+ " or \"visual\" to go to the visual\n"
+ " configuration interface (requires MGA/VGA display or\n"
+ " serial terminal capable of displaying ANSI graphics)"
+#endif
+ ".\n");
+
+
while (1) {
printf("config> ");
cngets(input, 80);
@@ -2989,6 +2867,7 @@ set_num_eisa_slots(CmdParm *parms)
static int
quitfunc(CmdParm *parms)
{
+#ifdef USERCONFIG_BOOT
/*
* If kernel config supplied, and we are parsing it, and -c also supplied,
* ignore a quit command, This provides a safety mechanism to allow
@@ -2996,6 +2875,7 @@ quitfunc(CmdParm *parms)
*/
if ((boothowto & RB_CONFIG) && userconfig_boot_parsing)
return 0;
+#endif
return 1;
}
@@ -3038,7 +2918,7 @@ helpfunc(CmdParm *parms)
return 0;
}
-#if defined(INTRO_USERCONFIG)
+#if defined(USERCONFIG_BOOT)
#if defined (VISUAL_USERCONFIG)
static void
@@ -3172,10 +3052,7 @@ introfunc(CmdParm *parms)
return visuserconfig();
else {
putxy(0, 1, "Type \"help\" for help or \"quit\" to exit.");
- /* enable quitfunc */
- userconfig_boot_parsing=0;
move (0, 3);
- boothowto |= RB_CONFIG; /* force -c */
return 0;
}
break;
@@ -3204,14 +3081,12 @@ lspnp ()
"mem 0x%x 0x%x 0x%x 0x%x";
char buf[256];
if (lineno >= 23) {
- if (!userconfig_boot_parsing) {
- printf("<More> ");
- if (getchar() == 'q') {
- printf("quit\n");
- return (1);
- }
- printf("\n");
+ printf("<More> ");
+ if (getchar() == 'q') {
+ printf("quit\n");
+ return (1);
}
+ printf("\n");
lineno = 0;
}
if (lineno == 0 || first)
@@ -3257,13 +3132,11 @@ lsdevtab(struct isa_device *dt)
if (lineno >= 23) {
printf("<More> ");
- if (!userconfig_boot_parsing) {
- if (getchar() == 'q') {
- printf("quit\n");
- return (1);
- }
- printf("\n");
+ if (getchar() == 'q') {
+ printf("quit\n");
+ return (1);
}
+ printf("\n");
lineno = 0;
}
if (lineno == 0) {
diff --git a/sys/pc98/pc98/atcompat_diskslice.c b/sys/pc98/pc98/atcompat_diskslice.c
index ad51bc05e3f6..c25afaf36e56 100644
--- a/sys/pc98/pc98/atcompat_diskslice.c
+++ b/sys/pc98/pc98/atcompat_diskslice.c
@@ -35,7 +35,7 @@
*
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
- * $Id: atcompat_diskslice.c,v 1.12 1998/08/10 16:55:54 kato Exp $
+ * $Id: atcompat_diskslice.c,v 1.11 1998/07/27 09:49:22 kato Exp $
*/
/*
@@ -423,7 +423,7 @@ atcompat_extended(dname, dev, strat, lp, ssp, ext_offset, ext_size,
sname = dsname(dname, dkunit(dev), WHOLE_DISK_SLICE,
RAW_PART, partname);
- snprintf(buf, sizeof(buf), "%s", sname);
+ strcpy(buf, sname);
if (strlen(buf) < sizeof buf - 11)
strcat(buf, "<extended>");
check_part(buf, dp, base_ext_offset, nsectors,
diff --git a/sys/pc98/pc98/clock.c b/sys/pc98/pc98/clock.c
index 1225f3157d4c..20744f80f8c0 100644
--- a/sys/pc98/pc98/clock.c
+++ b/sys/pc98/pc98/clock.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)clock.c 7.2 (Berkeley) 5/12/91
- * $Id: clock.c,v 1.64 1998/10/23 13:13:43 kato Exp $
+ * $Id: clock.c,v 1.62 1998/10/13 02:33:21 kato Exp $
*/
/*
@@ -136,7 +136,7 @@ static void setup_8254_mixed_mode __P((void));
*/
#define TIMER0_MAX_FREQ 20000
-int adjkerntz; /* local offset from GMT in seconds */
+int adjkerntz; /* local offset from GMT in seconds */
int disable_rtc_set; /* disable resettodr() if != 0 */
u_int idelayed;
int statclock_disable;
@@ -151,7 +151,7 @@ u_int stat_imask = SWI_CLOCK_MASK;
u_int timer_freq = TIMER_FREQ;
int timer0_max_count;
u_int tsc_freq;
-int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
+int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
static int beeping = 0;
static u_int clk_imask = HWI_MASK | SWI_MASK;
@@ -198,7 +198,7 @@ static unsigned i8254_get_timecount __P((struct timecounter *tc));
static unsigned tsc_get_timecount __P((struct timecounter *tc));
static void set_timer_freq(u_int freq, int intr_freq);
-static struct timecounter tsc_timecounter = {
+static struct timecounter tsc_timecounter[3] = {
tsc_get_timecount, /* get_timecount */
0, /* no poll_pps */
~0u, /* counter_mask */
@@ -207,9 +207,9 @@ static struct timecounter tsc_timecounter = {
};
SYSCTL_OPAQUE(_debug, OID_AUTO, tsc_timecounter, CTLFLAG_RD,
- &tsc_timecounter, sizeof(tsc_timecounter), "S,timecounter", "");
+ tsc_timecounter, sizeof(tsc_timecounter), "S,timecounter", "");
-static struct timecounter i8254_timecounter = {
+static struct timecounter i8254_timecounter[3] = {
i8254_get_timecount, /* get_timecount */
0, /* no poll_pps */
~0u, /* counter_mask */
@@ -218,7 +218,7 @@ static struct timecounter i8254_timecounter = {
};
SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD,
- &i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", "");
+ i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", "");
static void
clkintr(struct clockframe frame)
@@ -952,8 +952,8 @@ startrtclock()
}
set_timer_freq(timer_freq, hz);
- i8254_timecounter.tc_frequency = timer_freq;
- init_timecounter(&i8254_timecounter);
+ i8254_timecounter[0].tc_frequency = timer_freq;
+ init_timecounter(i8254_timecounter);
#ifndef CLK_USE_TSC_CALIBRATION
if (tsc_freq != 0) {
@@ -1002,8 +1002,8 @@ startrtclock()
#endif /* NAPM > 0 */
if (tsc_present && tsc_freq != 0) {
- tsc_timecounter.tc_frequency = tsc_freq;
- init_timecounter(&tsc_timecounter);
+ tsc_timecounter[0].tc_frequency = tsc_freq;
+ init_timecounter(tsc_timecounter);
}
#endif /* !defined(SMP) */
@@ -1070,8 +1070,8 @@ rtc_inb(void)
#endif /* PC-98 */
/*
- * Initialize the time of day register, based on the time base which is, e.g.
- * from a filesystem.
+ * Initialize the time of day register, based on the time base which is, e.g.
+ * from a filesystem.
*/
void
inittodr(time_t base)
@@ -1123,17 +1123,17 @@ inittodr(time_t base)
/* sec now contains the number of seconds, since Jan 1 1970,
in the local time zone */
#else /* IBM-PC */
- /* Look if we have a RTC present and the time is valid */
+ /* Look if we have a RTC present and the time is valid */
if (!(rtcin(RTC_STATUSD) & RTCSD_PWR))
goto wrong_time;
- /* wait for time update to complete */
- /* If RTCSA_TUP is zero, we have at least 244us before next update */
+ /* wait for time update to complete */
+ /* If RTCSA_TUP is zero, we have at least 244us before next update */
while (rtcin(RTC_STATUSA) & RTCSA_TUP);
days = 0;
#ifdef USE_RTC_CENTURY
- year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100;
+ year = readrtc(RTC_YEAR) + readrtc(RTC_CENTURY) * 100;
#else
year = readrtc(RTC_YEAR) + 1900;
if (year < 1970)
@@ -1141,21 +1141,21 @@ inittodr(time_t base)
#endif
if (year < 1970)
goto wrong_time;
- month = readrtc(RTC_MONTH);
- for (m = 1; m < month; m++)
- days += daysinmonth[m-1];
- if ((month > 2) && LEAPYEAR(year))
+ month = readrtc(RTC_MONTH);
+ for (m = 1; m < month; m++)
+ days += daysinmonth[m-1];
+ if ((month > 2) && LEAPYEAR(year))
days ++;
- days += readrtc(RTC_DAY) - 1;
+ days += readrtc(RTC_DAY) - 1;
yd = days;
for (y = 1970; y < year; y++)
- days += DAYSPERYEAR + LEAPYEAR(y);
+ days += DAYSPERYEAR + LEAPYEAR(y);
sec = ((( days * 24 +
readrtc(RTC_HRS)) * 60 +
readrtc(RTC_MIN)) * 60 +
readrtc(RTC_SEC));
- /* sec now contains the number of seconds, since Jan 1 1970,
- in the local time zone */
+ /* sec now contains the number of seconds, since Jan 1 1970,
+ in the local time zone */
#endif
sec += tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
@@ -1172,12 +1172,12 @@ inittodr(time_t base)
return;
wrong_time:
- printf("Invalid time in real time clock.\n");
- printf("Check and reset the date immediately!\n");
+ printf("Invalid time in real time clock.\n");
+ printf("Check and reset the date immediately!\n");
}
/*
- * Write system time back to RTC
+ * Write system time back to RTC
*/
void
resettodr()
@@ -1236,7 +1236,7 @@ resettodr()
/* Disable RTC updates and interrupts. */
writertc(RTC_STATUSB, RTCSB_HALT | RTCSB_24HR);
- /* Calculate local time to put in RTC */
+ /* Calculate local time to put in RTC */
tm -= tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0);
@@ -1244,7 +1244,7 @@ resettodr()
writertc(RTC_MIN, bin2bcd(tm%60)); tm /= 60; /* Write back Minutes */
writertc(RTC_HRS, bin2bcd(tm%24)); tm /= 24; /* Write back Hours */
- /* We have now the days since 01-01-1970 in tm */
+ /* We have now the days since 01-01-1970 in tm */
writertc(RTC_WDAY, (tm+4)%7); /* Write back Weekday */
for (y = 1970, m = DAYSPERYEAR + LEAPYEAR(y);
tm >= m;
@@ -1467,7 +1467,7 @@ sysctl_machdep_i8254_freq SYSCTL_HANDLER_ARGS
if (timer0_state != RELEASED)
return (EBUSY); /* too much trouble to handle */
set_timer_freq(freq, hz);
- i8254_timecounter.tc_frequency = freq;
+ i8254_timecounter[0].tc_frequency = freq;
}
return (error);
}
@@ -1487,7 +1487,7 @@ sysctl_machdep_tsc_freq SYSCTL_HANDLER_ARGS
error = sysctl_handle_opaque(oidp, &freq, sizeof freq, req);
if (error == 0 && req->newptr != NULL) {
tsc_freq = freq;
- tsc_timecounter.tc_frequency = tsc_freq;
+ tsc_timecounter[0].tc_frequency = tsc_freq;
}
return (error);
}
diff --git a/sys/pc98/pc98/diskslice_machdep.c b/sys/pc98/pc98/diskslice_machdep.c
index 5370462dcd06..e2688ffde2f6 100644
--- a/sys/pc98/pc98/diskslice_machdep.c
+++ b/sys/pc98/pc98/diskslice_machdep.c
@@ -35,7 +35,7 @@
*
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
- * $Id: diskslice_machdep.c,v 1.16 1998/08/10 16:55:54 kato Exp $
+ * $Id: diskslice_machdep.c,v 1.15 1998/07/27 09:49:23 kato Exp $
*/
/*
@@ -470,7 +470,7 @@ reread_mbr:
sp->ds_size = pc98_size;
sp->ds_type = dp->dp_mid;
sp->ds_subtype = dp->dp_sid;
- strncpy(sp->ds_name, dp->dp_name, sizeof(sp->ds_name));
+ strncpy(sp->ds_name, dp->dp_name, 16);
#else
sp->ds_offset = mbr_offset + dp->dp_start;
sp->ds_size = dp->dp_size;
@@ -580,7 +580,7 @@ extended(dname, dev, strat, lp, ssp, ext_offset, ext_size, base_ext_offset,
sname = dsname(dname, dkunit(dev), WHOLE_DISK_SLICE,
RAW_PART, partname);
- snprintf(buf, sizeof(buf), "%s", sname);
+ strcpy(buf, sname);
if (strlen(buf) < sizeof buf - 11)
strcat(buf, "<extended>");
check_part(buf, dp, base_ext_offset, nsectors,
@@ -611,7 +611,7 @@ extended(dname, dev, strat, lp, ssp, ext_offset, ext_size, base_ext_offset,
sp->ds_size = pc98_size;
sp->ds_type = dp->dp_mid;
sp->ds_subtype = dp->dp_sid;
- strncpy(sp->ds_name, dp->dp_name, sizeof(sp->ds_name));
+ strncpy(sp->ds_name, dp->dp_name, 16);
#else
sp->ds_offset = ext_offset + dp->dp_start;
sp->ds_size = dp->dp_size;
diff --git a/sys/pc98/pc98/fd.c b/sys/pc98/pc98/fd.c
index 90f230f5e871..889c066e6e25 100644
--- a/sys/pc98/pc98/fd.c
+++ b/sys/pc98/pc98/fd.c
@@ -5,10 +5,6 @@
* This code is derived from software contributed to Berkeley by
* Don Ahn.
*
- * Libretto PCMCIA floppy support by David Horwitt (dhorwitt@ucsd.edu)
- * aided by the Linux floppy driver modifications from David Bateman
- * (dbateman@eng.uts.edu.au).
- *
* Copyright (c) 1993, 1994 by
* jc@irbs.UUCP (John Capo)
* vak@zebub.msk.su (Serge Vakulenko)
@@ -47,10 +43,14 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.49 1999/01/16 11:40:02 kato Exp $
+ * $Id: fd.c,v 1.40 1998/09/15 14:07:08 kato Exp $
*
*/
+#include "ft.h"
+#if NFT < 1
+#undef NFDC
+#endif
#include "fd.h"
#include "opt_devfs.h"
#include "opt_fdc.h"
@@ -84,6 +84,10 @@
#endif
#include <i386/isa/fdc.h>
#include <machine/stdarg.h>
+#if NFT > 0
+#include <sys/ftape.h>
+#include <i386/isa/ftreg.h>
+#endif
#ifdef DEVFS
#include <sys/devfsext.h>
#endif /* DEVFS */
@@ -93,10 +97,6 @@
/* configuration flags */
#define FDC_PRETEND_D0 (1 << 0) /* pretend drive 0 to be there */
-#ifdef FDC_YE
-#define FDC_IS_PCMCIA (1 << 1) /* if successful probe, then it's
- a PCMCIA device */
-#endif
/* internally used only, not really from CMOS: */
#define RTCFDT_144M_PRETENDED 0x1000
@@ -285,9 +285,15 @@ nrd_info(addr)
* fdsu is the floppy drive unit number on that controller. (sub-unit) *
\***********************************************************************/
-#ifdef FDC_YE
-#include "card.h"
-static int yeattach(struct isa_device *);
+#if NFT > 0
+int ftopen(dev_t, int);
+int ftintr(ftu_t ftu);
+int ftclose(dev_t, int);
+void ftstrategy(struct buf *);
+int ftioctl(dev_t, unsigned long, caddr_t, int, struct proc *);
+int ftdump(dev_t);
+int ftsize(dev_t);
+int ftattach(struct isa_device *, struct isa_device *, int);
#endif
/* autoconfig functions */
@@ -310,7 +316,6 @@ static int fd_in(fdcu_t, int *);
static void fdstart(fdcu_t);
static timeout_t fd_iotimeout;
static timeout_t fd_pseudointr;
-static ointhand2_t fdintr;
static int fdstate(fdcu_t, fdc_p);
static int retrier(fdcu_t);
static int fdformat(dev_t, struct fd_formb *, struct proc *);
@@ -333,9 +338,6 @@ static int fifo_threshold = 8; /* XXX: should be accessible via sysctl */
#define MOTORWAIT 10
#define IOTIMEDOUT 11
#define RESETCOMPLETE 12
-#ifdef FDC_YE
-#define PIOREAD 13
-#endif
#ifdef FDC_DEBUG
static char const * const fdstates[] =
@@ -353,9 +355,6 @@ static char const * const fdstates[] =
"MOTORWAIT",
"IOTIMEDOUT",
"RESETCOMPLETE",
-#ifdef FDC_YE
-"PIOREAD",
-#endif
};
/* CAUTION: fd_debug causes huge amounts of logging output */
@@ -367,91 +366,6 @@ static int volatile fd_debug = 0;
#define TRACE1(arg1, arg2)
#endif /* FDC_DEBUG */
-#ifdef FDC_YE
-#if NCARD > 0
-#include <sys/select.h>
-#include <sys/module.h>
-#include <pccard/cardinfo.h>
-#include <pccard/driver.h>
-#include <pccard/slot.h>
-
-/*
- * PC-Card (PCMCIA) specific code.
- */
-static int yeinit(struct pccard_devinfo *); /* init device */
-static void yeunload(struct pccard_devinfo *); /* Disable driver */
-static int yeintr(struct pccard_devinfo *); /* Interrupt handler */
-
-PCCARD_MODULE(fdc, yeinit, yeunload, yeintr, 0, bio_imask);
-
-/*
- * this is the secret PIO data port (offset from base)
- */
-#define FDC_YE_DATAPORT 6
-
-/*
- * Initialize the device - called from Slot manager.
- */
-static int yeinit(struct pccard_devinfo *devi)
-{
- fdc_p fdc = &fdc_data[devi->isahd.id_unit];
-
- /* validate unit number. */
- if (devi->isahd.id_unit >= NFDC)
- return(ENODEV);
- fdc->baseport = devi->isahd.id_iobase;
- /*
- * reset controller
- */
- outb(fdc->baseport+FDOUT, 0);
- DELAY(100);
- outb(fdc->baseport+FDOUT, FDO_FRST);
-
- /*
- * wire into system
- */
- if (yeattach(&devi->isahd) == 0)
- return(ENXIO);
-
- return(0);
-}
-
-/*
- * yeunload - unload the driver and clear the table.
- * XXX TODO:
- * This is usually called when the card is ejected, but
- * can be caused by a modunload of a controller driver.
- * The idea is to reset the driver's view of the device
- * and ensure that any driver entry points such as
- * read and write do not hang.
- */
-static void yeunload(struct pccard_devinfo *devi)
-{
- if (fd_data[devi->isahd.id_unit].type == NO_TYPE)
- return;
-
- /*
- * this prevents Fdopen() and fdstrategy() from attempting
- * to access unloaded controller
- */
- fd_data[devi->isahd.id_unit].type = NO_TYPE;
-
- printf("fdc%d: unload\n", devi->isahd.id_unit);
-}
-
-/*
- * yeintr - Shared interrupt called from
- * front end of PC-Card handler.
- */
-static int yeintr(struct pccard_devinfo *devi)
-{
- fdintr((fdcu_t)devi->isahd.id_unit);
- return(1);
-}
-#endif /* NCARD > 0 */
-#endif /* FDC_YE */
-
-
/* autoconfig structure */
struct isa_driver fdcdriver = {
@@ -490,7 +404,7 @@ fdc_err(fdcu_t fdcu, const char *s)
printf("fdc%d: %s", fdcu, s);
else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX)
printf("fdc%d: too many errors, not logging any more\n",
- fdcu);
+ fdcu);
}
return FD_FAILED;
@@ -520,7 +434,7 @@ fd_cmd(fdcu_t fdcu, int n_out, ...)
if (out_fdc(fdcu, va_arg(ap, int)) < 0)
{
char msg[50];
- snprintf(msg, sizeof(msg),
+ sprintf(msg,
"cmd %x failed at out byte %d of %d\n",
cmd, n + 1, n_out);
return fdc_err(fdcu, msg);
@@ -533,7 +447,7 @@ fd_cmd(fdcu_t fdcu, int n_out, ...)
if (fd_in(fdcu, ptr) < 0)
{
char msg[50];
- snprintf(msg, sizeof(msg),
+ sprintf(msg,
"cmd %02x failed at in byte %d of %d\n",
cmd, n + 1, n_in);
return fdc_err(fdcu, msg);
@@ -783,14 +697,6 @@ fdprobe(struct isa_device *dev)
{
return(0);
}
-#ifdef FDC_YE
- /*
- * don't succeed on probe; wait
- * for PCCARD subsystem to do it
- */
- if (dev->id_flags & FDC_IS_PCMCIA)
- return(0);
-#endif
return (IO_FDCSIZE);
}
@@ -806,6 +712,9 @@ fdattach(struct isa_device *dev)
fdc_p fdc = fdc_data + fdcu;
fd_p fd;
int fdsu, st0, st3, i;
+#if NFT > 0
+ int unithasfd;
+#endif
struct isa_device *fdup;
int ic_type = 0;
#ifdef DEVFS
@@ -814,7 +723,6 @@ fdattach(struct isa_device *dev)
int typesize;
#endif
- dev->id_ointr = fdintr;
fdc->fdcu = fdcu;
fdc->flags |= FDC_ATTACHED;
#ifdef PC98
@@ -845,7 +753,7 @@ fdattach(struct isa_device *dev)
continue;
fdu = fdup->id_unit;
fd = &fd_data[fdu];
- if (fdu >= (NFD))
+ if (fdu >= (NFD+NFT))
continue;
fdsu = fdup->id_physid;
/* look up what bios thinks we have */
@@ -901,11 +809,29 @@ fdattach(struct isa_device *dev)
#else
if ((fdt == RTCFDT_NONE)
#endif
+#if NFT > 0
+ || (fdsu >= DRVS_PER_CTLR)) {
+#else
) {
#ifdef PC98
fd->fdc = fdc;
#endif
fd->type = NO_TYPE;
+#endif
+#if NFT > 0
+ /* If BIOS says no floppy, or > 2nd device */
+ /* Probe for and attach a floppy tape. */
+ /* Tell FT if there was already a disk */
+ /* with this unit number found. */
+
+ unithasfd = 0;
+ if (fdu < NFD && fd->type != NO_TYPE)
+ unithasfd = 1;
+ if (ftattach(dev, fdup, unithasfd))
+ continue;
+ if (fdsu < DRVS_PER_CTLR)
+ fd->type = NO_TYPE;
+#endif
continue;
}
@@ -952,7 +878,7 @@ fdattach(struct isa_device *dev)
enable_fifo(fdc) == 0) {
printf("fdc%d: FIFO enabled", fdcu);
printf(", %d bytes threshold\n",
- fifo_threshold);
+ fifo_threshold);
}
}
if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&
@@ -1141,10 +1067,10 @@ fdattach(struct isa_device *dev)
}
for (i = 0; i < MAXPARTITIONS; i++) {
- fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0],
+ fd->bdevs[1 + NUMDENS + i] = devfs_link(fd->bdevs[0],
"fd%d%c", fdu, 'a' + i);
fd->cdevs[1 + NUMDENS + i] =
- devfs_makelink(fd->cdevs[0],
+ devfs_link(fd->cdevs[0],
"rfd%d%c", fdu, 'a' + i);
}
#endif /* DEVFS */
@@ -1163,138 +1089,6 @@ fdattach(struct isa_device *dev)
-#ifdef FDC_YE
-/*
- * this is a subset of fdattach() optimized for the Y-E Data
- * PCMCIA floppy drive.
- */
-static int yeattach(struct isa_device *dev)
-{
- fdcu_t fdcu = dev->id_unit;
- fdc_p fdc = fdc_data + fdcu;
- fdsu_t fdsu = 0; /* assume 1 drive per YE controller */
- fdu_t fdu;
- fd_p fd;
- int st0, st3, i;
-#ifdef DEVFS
- int mynor;
- int typemynor;
- int typesize;
-#endif
- fdc->fdcu = fdcu;
- /*
- * the FDC_PCMCIA flag is used to to indicate special PIO is used
- * instead of DMA
- */
- fdc->flags = FDC_ATTACHED|FDC_PCMCIA;
- fdc->state = DEVIDLE;
- /* reset controller, turn motor off, clear fdout mirror reg */
- outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
- bufq_init(&fdc->head);
- /*
- * assume 2 drives/ "normal" controller
- */
- fdu = fdcu * 2;
- if (fdu >= NFD) {
- printf("fdu %d >= NFD\n",fdu);
- return(0);
- };
- fd = &fd_data[fdu];
-
- set_motor(fdcu, fdsu, TURNON);
- DELAY(1000000); /* 1 sec */
- fdc->fdct = FDC_NE765;
-
- if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&
- (st3 & NE7_ST3_T0)) {
- /* if at track 0, first seek inwards */
- /* seek some steps: */
- (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0);
- DELAY(300000); /* ...wait a moment... */
- (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
- }
-
- /* If we're at track 0 first seek inwards. */
- if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) {
- /* Seek some steps... */
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
- /* ...wait a moment... */
- DELAY(300000);
- /* make ctrlr happy: */
- (void)fd_sense_int(fdc, 0, 0);
- }
- }
-
- for(i = 0; i < 2; i++) {
- /*
- * we must recalibrate twice, just in case the
- * heads have been beyond cylinder 76, since most
- * FDCs still barf when attempting to recalibrate
- * more than 77 steps
- */
- /* go back to 0: */
- if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
- /* a second being enough for full stroke seek*/
- DELAY(i == 0? 1000000: 300000);
-
- /* anything responding? */
- if (fd_sense_int(fdc, &st0, 0) == 0 &&
- (st0 & NE7_ST0_EC) == 0)
- break; /* already probed succesfully */
- }
- }
-
- set_motor(fdcu, fdsu, TURNOFF);
-
- if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
- return(0);
-
- fd->track = FD_NO_TRACK;
- fd->fdc = fdc;
- fd->fdsu = fdsu;
- fd->options = 0;
- printf("fdc%d: 1.44MB 3.5in PCMCIA\n", fdcu);
- fd->type = FD_1440;
-
-#ifdef DEVFS
- mynor = fdcu << 6;
- fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640,
- "fd%d", fdu);
- fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640,
- "rfd%d", fdu);
- /*
- * XXX this and the lookup in Fdopen() should be
- * data driven.
- */
- typemynor = mynor | FD_1440;
- typesize = fd_types[FD_1440 - 1].size / 2;
- /*
- * XXX all these conversions give bloated code and
- * confusing names.
- */
- if (typesize == 1476)
- typesize = 1480;
- if (typesize == 1722)
- typesize = 1720;
- fd->bdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor,
- DV_BLK, UID_ROOT, GID_OPERATOR,
- 0640, "fd%d.%d", fdu, typesize);
- fd->cdevs[FD_1440] = devfs_add_devswf(&fd_cdevsw, typemynor,
- DV_CHR, UID_ROOT, GID_OPERATOR,
- 0640,"rfd%d.%d", fdu, typesize);
- for (i = 0; i < MAXPARTITIONS; i++) {
- fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0],
- "fd%d%c", fdu, 'a' + i);
- fd->cdevs[1 + NUMDENS + i] = devfs_makelink(fd->cdevs[0],
- "rfd%d%c", fdu, 'a' + i);
- }
-#endif /* DEVFS */
- return (1);
-}
-#endif
-
/****************************************************************************/
/* motor control stuff */
/* remember to not deselect the drive we're working on */
@@ -1532,6 +1326,11 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
int type = FDTYPE(minor(dev));
fdc_p fdc;
+#if NFT > 0
+ /* check for a tape open */
+ if (type & F_TAPE_TYPE)
+ return(ftopen(dev, flags));
+#endif
/* check bounds */
if (fdu >= NFD)
return(ENXIO);
@@ -1611,6 +1410,12 @@ fdclose(dev_t dev, int flags, int mode, struct proc *p)
{
fdu_t fdu = FDUNIT(minor(dev));
+#if NFT > 0
+ int type = FDTYPE(minor(dev));
+
+ if (type & F_TAPE_TYPE)
+ return ftclose(dev, flags);
+#endif
fd_data[fdu].flags &= ~FD_OPEN;
fd_data[fdu].options &= ~FDOPT_NORETRY;
@@ -1648,18 +1453,21 @@ fdstrategy(struct buf *bp)
fd = &fd_data[fdu];
fdc = fd->fdc;
fdcu = fdc->fdcu;
-#ifdef FDC_YE
- if (fd->type == NO_TYPE) {
- bp->b_error = ENXIO;
+
+#if NFT > 0
+ if (FDTYPE(minor(bp->b_dev)) & F_TAPE_TYPE) {
+ /* ft tapes do not (yet) support strategy i/o */
+ bp->b_error = ENODEV;
bp->b_flags |= B_ERROR;
- /*
- * I _refuse_ to use a goto
- */
- biodone(bp);
- return;
- };
+ goto bad;
+ }
+ /* check for controller already busy with tape */
+ if (fdc->flags & FDC_TAPE_BUSY) {
+ bp->b_error = EBUSY;
+ bp->b_flags |= B_ERROR;
+ goto bad;
+ }
#endif
-
fdblk = 128 << (fd->ft->secsize);
if (!(bp->b_flags & B_FORMAT)) {
if ((fdu >= NFD) || (bp->b_blkno < 0)) {
@@ -1797,46 +1605,21 @@ fd_pseudointr(void *arg1)
* keep calling the state machine until it returns a 0 *
* ALWAYS called at SPLBIO *
\***********************************************************************/
-static void
+void
fdintr(fdcu_t fdcu)
{
fdc_p fdc = fdc_data + fdcu;
+#if NFT > 0
+ fdu_t fdu = fdc->fdu;
+
+ if (fdc->flags & FDC_TAPE_BUSY)
+ (ftintr(fdu));
+ else
+#endif
while(fdstate(fdcu, fdc))
;
}
-#ifdef FDC_YE
-/*
- * magic pseudo-DMA initialization for YE FDC. Sets count and
- * direction
- */
-#define SET_BCDR(wr,cnt,port) outb(port,(((cnt)-1) & 0xff)); \
- outb(port+1,((wr ? 0x80 : 0) | ((((cnt)-1) >> 8) & 0x7f)))
-
-/*
- * fdcpio(): perform programmed IO read/write for YE PCMCIA floppy
- */
-static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count)
-{
- u_char *cptr = (u_char *)addr;
- fdc_p fdc = &fdc_data[fdcu];
- int io = fdc->baseport;
-
- if (flags & B_READ) {
- if (fdc->state != PIOREAD) {
- fdc->state = PIOREAD;
- return(0);
- };
- SET_BCDR(0,count,io);
- insb(io+FDC_YE_DATAPORT,cptr,count);
- } else {
- outsb(io+FDC_YE_DATAPORT,cptr,count);
- SET_BCDR(0,count,io);
- };
- return(1);
-}
-#endif /* FDC_YE */
-
/***********************************************************************\
* The controller state machine. *
* if it returns a non zero value, it should be called again immediatly *
@@ -1844,6 +1627,7 @@ static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count)
static int
fdstate(fdcu_t fdcu, fdc_p fdc)
{
+ struct subdev *sd;
int read, format, head, i, sec = 0, sectrac, st0, cyl, st3;
unsigned blknum = 0, b_cylinder = 0;
fdu_t fdu = fdc->fdu;
@@ -1852,15 +1636,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
struct fd_formb *finfo = NULL;
size_t fdblk;
- bp = fdc->bp;
- if (bp == NULL) {
- bp = bufq_first(&fdc->head);
- if (bp != NULL) {
- bufq_remove(&fdc->head, bp);
- fdc->bp = bp;
- }
- }
- if (bp == NULL) {
+ bp = bufq_first(&fdc->head);
+ if(!bp) {
/***********************************************\
* nothing left for this controller to do *
* Force into the IDLE state, *
@@ -2083,11 +1860,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
#ifdef EPSON_NRDISK
if (fdu != nrdu) {
#endif /* EPSON_NRDISK */
-#ifdef FDC_YE
- if (!(fdc->flags & FDC_PCMCIA))
-#endif
- isa_dmastart(bp->b_flags, bp->b_data+fd->skip,
- format ? bp->b_bcount : fdblk, fdc->dmachan);
+ isa_dmastart(bp->b_flags, bp->b_data+fd->skip,
+ format ? bp->b_bcount : fdblk, fdc->dmachan);
sectrac = fd->ft->sectrac;
sec = blknum % (sectrac * fd->ft->heads);
head = sec / sectrac;
@@ -2128,12 +1902,6 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
if(format)
{
-#ifdef FDC_YE
- if (fdc->flags & FDC_PCMCIA)
- (void)fdcpio(fdcu,bp->b_flags,
- bp->b_data+fd->skip,
- bp->b_bcount);
-#endif
/* formatting */
if(fd_cmd(fdcu, 6,
NE7CMD_FORMAT,
@@ -2154,24 +1922,6 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
}
else
{
-#ifdef FDC_YE
- if (fdc->flags & FDC_PCMCIA) {
- /*
- * this seems to be necessary even when
- * reading data
- */
- SET_BCDR(1,fdblk,fdc->baseport);
-
- /*
- * perform the write pseudo-DMA before
- * the WRITE command is sent
- */
- if (!read)
- (void)fdcpio(fdcu,bp->b_flags,
- bp->b_data+fd->skip,
- fdblk);
- }
-#endif
if (fd_cmd(fdcu, 9,
(read ? NE7CMD_READ : NE7CMD_WRITE),
head << 2 | fdu, /* head & unit */
@@ -2192,24 +1942,6 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
return(retrier(fdcu));
}
}
-#ifdef FDC_YE
- if (fdc->flags & FDC_PCMCIA)
- /*
- * if this is a read, then simply await interrupt
- * before performing PIO
- */
- if (read && !fdcpio(fdcu,bp->b_flags,
- bp->b_data+fd->skip,fdblk)) {
- fd->tohandle = timeout(fd_iotimeout,
- (caddr_t)fdcu, hz);
- return(0); /* will return later */
- };
-
- /*
- * write (or format) operation will fall through and
- * await completion interrupt
- */
-#endif
fdc->state = IOCOMPLETE;
fd->tohandle = timeout(fd_iotimeout, (caddr_t)fdcu, hz);
return(0); /* will return later */
@@ -2243,16 +1975,6 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdc->state = IOCOMPLETE;
}
#endif
-#ifdef FDC_YE
- case PIOREAD:
- /*
- * actually perform the PIO read. The IOCOMPLETE case
- * removes the timeout for us.
- */
- (void)fdcpio(fdcu,bp->b_flags,bp->b_data+fd->skip,fdblk);
- fdc->state = IOCOMPLETE;
- /* FALLTHROUGH */
-#endif
case IOCOMPLETE: /* IO DONE, post-analyze */
#ifdef EPSON_NRDISK
if (fdu != nrdu)
@@ -2279,11 +2001,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
#ifdef EPSON_NRDISK
if (fdu != nrdu) {
#endif /* EPSON_NRDISK */
-#ifdef FDC_YE
- if (!(fdc->flags & FDC_PCMCIA))
-#endif
- isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
- format ? bp->b_bcount : fdblk, fdc->dmachan);
+ isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
+ format ? bp->b_bcount : fdblk, fdc->dmachan);
#ifdef EPSON_NRDISK
}
else nrd_LED_off();
@@ -2322,7 +2041,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
{
/* ALL DONE */
fd->skip = 0;
- fdc->bp = NULL;
+ bufq_remove(&fdc->head, bp);
/* Tell devstat we have finished with the transaction */
devstat_end_transaction(&fd->device_stats,
bp->b_bcount - bp->b_resid,
@@ -2451,10 +2170,12 @@ static int
retrier(fdcu)
fdcu_t fdcu;
{
+ struct subdev *sd;
fdc_p fdc = fdc_data + fdcu;
register struct buf *bp;
+ int fdu;
- bp = fdc->bp;
+ bp = bufq_first(&fdc->head);
if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY)
goto fail;
@@ -2498,7 +2219,7 @@ retrier(fdcu)
bp->b_flags |= B_ERROR;
bp->b_error = EIO;
bp->b_resid += bp->b_bcount - fdc->fd->skip;
- fdc->bp = NULL;
+ bufq_remove(&fdc->head, bp);
/* Tell devstat we have finished with the transaction */
devstat_end_transaction(&fdc->fd->device_stats,
@@ -2607,6 +2328,14 @@ fdioctl(dev, cmd, addr, flag, p)
char buffer[DEV_BSIZE];
int error = 0;
+#if NFT > 0
+ int type = FDTYPE(minor(dev));
+
+ /* check for a tape ioctl */
+ if (type & F_TAPE_TYPE)
+ return ftioctl(dev, cmd, addr, flag, p);
+#endif
+
fdblk = 128 << fd->ft->secsize;
#ifdef PC98
diff --git a/sys/pc98/pc98/if_ed.c b/sys/pc98/pc98/if_ed.c
index b34898e3e80e..9b7f815e1d28 100644
--- a/sys/pc98/pc98/if_ed.c
+++ b/sys/pc98/pc98/if_ed.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_ed.c,v 1.57 1998/12/31 03:23:39 kato Exp $
+ * $Id: if_ed.c,v 1.53 1998/10/08 17:04:58 kato Exp $
*/
/*
@@ -49,7 +49,6 @@
* MELCO LPC-TJ, LPC-TS, LGY-98, LGH-98, IND-SP, IND-SS, EGY-98
* PLANET SMART COM CREDITCARD/2000 PCMCIA, EN-2298
* Contec C-NET(98), C-NET(98)E, C-NET(98)L, C-NET(98)E-A, C-NET(98)L-A
- * SMC EtherEZ98
*
* Modified for FreeBSD(98) 2.2 by KATO T. of Nagoya University.
*
@@ -180,7 +179,6 @@ static int ed_attach __P((struct ed_softc *, int, int));
static int ed_attach_isa __P((struct isa_device *));
static void ed_init __P((void *));
-static ointhand2_t edintr;
static int ed_ioctl __P((struct ifnet *, u_long, caddr_t));
static int ed_probe __P((struct isa_device *));
static void ed_start __P((struct ifnet *));
@@ -241,7 +239,6 @@ static u_long ds_crc __P((u_char *ep));
#endif
#if NCARD > 0
#include <sys/select.h>
-#include <sys/module.h>
#include <pccard/cardinfo.h>
#include <pccard/slot.h>
@@ -252,7 +249,17 @@ static int edinit __P((struct pccard_devinfo *));
static void edunload __P((struct pccard_devinfo *));
static int card_intr __P((struct pccard_devinfo *));
-PCCARD_MODULE(ed, edinit, edunload, card_intr, 0, net_imask);
+static struct pccard_device ed_info = {
+ "ed",
+ edinit,
+ edunload,
+ card_intr,
+ 0, /* Attributes - presently unused */
+ &net_imask /* Interrupt mask for device */
+ /* XXX - Should this also include net_imask? */
+};
+
+DATA_SET(pccarddrv_set, ed_info);
/*
* Initialize the device - called from Slot manager.
@@ -349,16 +356,6 @@ static unsigned short ed_intr_mask[] = {
* Interrupt conversion table for 83C790
*/
static unsigned short ed_790_intr_mask[] = {
-#ifdef PC98
- 0,
- IRQ3,
- IRQ5,
- IRQ6,
- 0,
- IRQ9,
- IRQ12,
- IRQ13
-#else
0,
IRQ9,
IRQ3,
@@ -367,7 +364,6 @@ static unsigned short ed_790_intr_mask[] = {
IRQ10,
IRQ11,
IRQ15
-#endif
};
/*
@@ -2485,7 +2481,6 @@ ed_attach_isa(isa_dev)
struct ed_softc *sc = &ed_softc[unit];
int flags = isa_dev->id_flags;
- isa_dev->id_ointr = edintr;
return ed_attach(sc, unit, flags);
}
@@ -3322,7 +3317,7 @@ edintr_sc(sc)
}
}
-static void
+void
edintr(unit)
int unit;
{
@@ -4283,7 +4278,7 @@ edpnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
dev->id_iobase = d.port[0];
dev->id_irq = (1 << d.irq[0]);
- dev->id_ointr = edintr;
+ dev->id_intr = edintr;
dev->id_drq = -1;
if (dev->id_driver == NULL) {
diff --git a/sys/pc98/pc98/if_ed98.h b/sys/pc98/pc98/if_ed98.h
index 19d07d08dd07..632006437273 100644
--- a/sys/pc98/pc98/if_ed98.h
+++ b/sys/pc98/pc98/if_ed98.h
@@ -26,7 +26,7 @@
*/
/*
- * PC-9801 specific definitions for DP8390/SMC8216 NICs.
+ * PC-9801 specific definitions for National Semiconductor DP8390 NIC.
*/
#ifndef __PC98_PC98_IF_ED98_H__
#define __PC98_PC98_IF_ED98_H__
@@ -47,22 +47,30 @@ static int pc98_set_register_unit __P((struct ed_softc *sc, int type, int iobase
/*
* Register offsets/total
*/
+#ifdef ED_NOVELL_NIC_OFFSET
#undef ED_NOVELL_NIC_OFFSET
+#endif
#define ED_NOVELL_NIC_OFFSET sc->edreg.nic_offset
+#ifdef ED_NOVELL_ASIC_OFFSET
#undef ED_NOVELL_ASIC_OFFSET
+#endif
#define ED_NOVELL_ASIC_OFFSET sc->edreg.asic_offset
/*
* Remote DMA data register; for reading or writing to the NIC mem
* via programmed I/O (offset from ASIC base).
*/
+#ifdef ED_NOVELL_DATA
#undef ED_NOVELL_DATA
+#endif
#define ED_NOVELL_DATA sc->edreg.data
/*
* Reset register; reading from this register causes a board reset.
*/
+#ifdef ED_NOVELL_RESET
#undef ED_NOVELL_RESET
+#endif
#define ED_NOVELL_RESET sc->edreg.reset
/*
@@ -82,20 +90,20 @@ static int pc98_set_register_unit __P((struct ed_softc *sc, int type, int iobase
* 0xa0 Contec C-NET(98).
* 0xb0 Contec C-NET(98)E/L.
*/
-#define ED_TYPE98_BASE 0x80
+#define ED_TYPE98_BASE 0x10
-#define ED_TYPE98_GENERIC 0x80
-#define ED_TYPE98_LPC 0x81
-#define ED_TYPE98_BDN 0x82
-#define ED_TYPE98_EGY 0x83
-#define ED_TYPE98_LGY 0x84
-#define ED_TYPE98_ICM 0x85
-#define ED_TYPE98_SIC 0x86
-#define ED_TYPE98_108 0x88
-#define ED_TYPE98_LA98 0x89
-#define ED_TYPE98_CNET98 0x8a
-#define ED_TYPE98_CNET98EL 0x8b
-#define ED_TYPE98_UE2212 0x8c
+#define ED_TYPE98_GENERIC 0x10
+#define ED_TYPE98_LPC 0x11
+#define ED_TYPE98_BDN 0x12
+#define ED_TYPE98_EGY 0x13
+#define ED_TYPE98_LGY 0x14
+#define ED_TYPE98_ICM 0x15
+#define ED_TYPE98_SIC 0x16
+#define ED_TYPE98_108 0x18
+#define ED_TYPE98_LA98 0x19
+#define ED_TYPE98_CNET98 0x1a
+#define ED_TYPE98_CNET98EL 0x1b
+#define ED_TYPE98_UE2212 0x1c
#define ED_TYPE98(x) (((x & 0xffff0000) >> 20) | ED_TYPE98_BASE)
#define ED_TYPE98SUB(x) ((x & 0xf0000) >> 16)
@@ -247,10 +255,14 @@ static int pc98_set_register_unit __P((struct ed_softc *sc, int type, int iobase
#define ED_P2_IMR sc->edreg.port[0x0f]
/* PCCARD */
+#ifdef ED_PC_MISC
#undef ED_PC_MISC
+#endif
#define ED_PC_MISC sc->edreg.pc_misc
+#ifdef ED_PC_RESET
#undef ED_PC_RESET
-#define ED_PC_RESET sc->edreg.pc_reset
+#endif
+#define ED_PC_RESET sc->edreg.pc_reset
/* LPC-T support */
#define LPCT_1d0_ON() \
@@ -385,9 +397,6 @@ pc98_set_register_unit(struct ed_softc *sc, int type, int iobase)
int nports;
sc->type = type;
- ED_PC_MISC = 0x18; /* dummy for NON-PCCard */
- ED_PC_RESET = 0x1f; /* same above */
-
switch (type) {
case ED_TYPE98_GENERIC:
sc->edreg.port = edp_generic;
@@ -395,6 +404,8 @@ pc98_set_register_unit(struct ed_softc *sc, int type, int iobase)
ED_NOVELL_ASIC_OFFSET = 0x0010;
ED_NOVELL_DATA = 0x0000;
ED_NOVELL_RESET = 0x000f;
+ ED_PC_MISC = 0x18;
+ ED_PC_RESET = 0x1f;
nports = 32;
break;
@@ -404,24 +415,30 @@ pc98_set_register_unit(struct ed_softc *sc, int type, int iobase)
ED_NOVELL_ASIC_OFFSET = 0x0200;
ED_NOVELL_DATA = 0x0000;
ED_NOVELL_RESET = 0x0100;
+ ED_PC_MISC = 0x18;
+ ED_PC_RESET = 0x1f;
nports = 16;
break;
case ED_TYPE98_EGY:
sc->edreg.port = edp_egy98;
- ED_NOVELL_NIC_OFFSET = 0x0000;
+ ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = 0x0200;
ED_NOVELL_DATA = 0x0000;
ED_NOVELL_RESET = 0x0100;
+ ED_PC_MISC = 0x18;
+ ED_PC_RESET = 0x1f;
nports = 16;
break;
case ED_TYPE98_ICM:
sc->edreg.port = edp_generic;
- ED_NOVELL_NIC_OFFSET = 0x0000;
+ ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = 0x0100;
ED_NOVELL_DATA = 0x0000;
ED_NOVELL_RESET = 0x000f;
+ ED_PC_MISC = 0x18;
+ ED_PC_RESET = 0x1f;
nports = 16;
break;
@@ -429,8 +446,10 @@ pc98_set_register_unit(struct ed_softc *sc, int type, int iobase)
sc->edreg.port = edp_la98;
ED_NOVELL_NIC_OFFSET = 0x0000;
ED_NOVELL_ASIC_OFFSET = 0x0100;
- ED_NOVELL_DATA = 0x0000;
+ ED_NOVELL_DATA = 0;
ED_NOVELL_RESET = 0xc100;
+ ED_PC_MISC = 0x18;
+ ED_PC_RESET = 0x1f;
nports = 1;
break;
@@ -438,8 +457,10 @@ pc98_set_register_unit(struct ed_softc *sc, int type, int iobase)
sc->edreg.port = edp_sic98;
ED_NOVELL_NIC_OFFSET = 0x0000;
ED_NOVELL_ASIC_OFFSET = 0x2000;
- ED_NOVELL_DATA = 0; /* dummy */
- ED_NOVELL_RESET = 0; /* dummy */
+ ED_NOVELL_DATA = 0x00; /* dummy */
+ ED_NOVELL_RESET = 0x00;
+ ED_PC_MISC = 0x18; /* dummy */
+ ED_PC_RESET = 0x1f; /* dummy */
nports = 1;
break;
@@ -457,58 +478,47 @@ pc98_set_register_unit(struct ed_softc *sc, int type, int iobase)
case ED_TYPE98_108:
sc->edreg.port = edp_nec108;
adj = (iobase & 0xf000) / 2;
- ED_NOVELL_NIC_OFFSET = 0x0000;
- ED_NOVELL_ASIC_OFFSET = (0x0888 | adj) - iobase;
- ED_NOVELL_DATA = 0x0000;
- ED_NOVELL_RESET = 0x0002;
+ ED_NOVELL_NIC_OFFSET = 0;
+ ED_NOVELL_ASIC_OFFSET = (0x888 | adj) - iobase;
+ ED_NOVELL_DATA = 0;
+ ED_NOVELL_RESET = 2;
+ ED_PC_MISC = 0x18;
+ ED_PC_RESET = 0x1f;
nports = 16;
break;
case ED_TYPE98_LA98:
sc->edreg.port = edp_la98;
- ED_NOVELL_NIC_OFFSET = 0x0000;
- ED_NOVELL_ASIC_OFFSET = 0x0100;
+ ED_NOVELL_NIC_OFFSET = 0;
+ ED_NOVELL_ASIC_OFFSET = 0x100;
ED_NOVELL_DATA = 0x0000;
ED_NOVELL_RESET = 0xf000;
+ ED_PC_MISC = 0x18;
+ ED_PC_RESET = 0x1f;
nports = 1;
break;
case ED_TYPE98_CNET98EL:
sc->edreg.port = edp_generic;
- ED_NOVELL_NIC_OFFSET = 0x0000;
+ ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = 0x0400;
ED_NOVELL_DATA = 0x000e;
- ED_NOVELL_RESET = 0; /* dummy */
+ ED_NOVELL_RESET = 0x0000; /* dummy */
+ ED_PC_RESET = 0x1f;
nports = 16;
break;
case ED_TYPE98_CNET98:
sc->edreg.port = edp_cnet98;
- ED_NOVELL_NIC_OFFSET = 0x0000;
+ ED_NOVELL_NIC_OFFSET = 0;
ED_NOVELL_ASIC_OFFSET = 0x0400;
- ED_NOVELL_DATA = 0; /* dummy */
- ED_NOVELL_RESET = 0; /* dummy */
+ ED_NOVELL_DATA = 0x0000;
+ ED_NOVELL_RESET = 0x0000; /* dummy */
+ ED_PC_RESET = 0x1f;
nports = 16;
break;
}
return nports;
}
-/*
- * SMC EtherEZ98(SMC8498BTA)
- *
- * A sample of kernel conf is as follows.
- * #device ed0 at isa? port 0x10d0 net irq 6 iomem 0xc8000 vector edintr
- */
-#undef ED_WD_NIC_OFFSET
-#define ED_WD_NIC_OFFSET 0x100 /* I/O base offset to NIC */
-#undef ED_WD_ASIC_OFFSET
-#define ED_WD_ASIC_OFFSET 0 /* I/O base offset to ASIC */
-/*
- * XXX - The I/O address range is fragmented in the EtherEZ98;
- * it occupies 16*2 I/O addresses, by the way.
- */
-#undef ED_WD_IO_PORTS
-#define ED_WD_IO_PORTS 16 /* # of i/o addresses used */
-
#endif /* __PC98_PC98_IF_ED98_H__ */
diff --git a/sys/pc98/pc98/if_fe.c b/sys/pc98/pc98/if_fe.c
new file mode 100644
index 000000000000..64b3091572cb
--- /dev/null
+++ b/sys/pc98/pc98/if_fe.c
@@ -0,0 +1,3824 @@
+/*
+ * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
+ *
+ * This software may be used, modified, copied, distributed, and sold, in
+ * both source and binary form provided that the above copyright, these
+ * terms and the following disclaimer are retained. The name of the author
+ * and/or the contributor may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR 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: if_fe.c,v 1.33 1998/10/08 17:06:32 kato Exp $
+ *
+ * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards.
+ * To be used with FreeBSD 2.x
+ * Contributed by M. Sekiguchi. <seki@sysrap.cs.fujitsu.co.jp>
+ *
+ * This version is intended to be a generic template for various
+ * MB86960A/MB86965A based Ethernet cards. It currently supports
+ * Fujitsu FMV-180 series for ISA and Allied-Telesis AT1700/RE2000
+ * series for ISA, as well as Fujitsu MBH10302 PC card.
+ * There are some currently-
+ * unused hooks embedded, which are primarily intended to support
+ * other types of Ethernet cards, but the author is not sure whether
+ * they are useful.
+ *
+ * This version also includes some alignments for
+ * RE1000/RE1000+/ME1500 support. It is incomplete, however, since the
+ * cards are not for AT-compatibles. (They are for PC98 bus -- a
+ * proprietary bus architecture available only in Japan.) Further
+ * work for PC98 version will be available as a part of FreeBSD(98)
+ * project.
+ *
+ * This software is a derivative work of if_ed.c version 1.56 by David
+ * Greenman available as a part of FreeBSD 2.0 RELEASE source distribution.
+ *
+ * The following lines are retained from the original if_ed.c:
+ *
+ * Copyright (C) 1993, David Greenman. This software may be used, modified,
+ * copied, distributed, and sold, in both source and binary form provided
+ * that the above copyright and these terms are retained. Under no
+ * circumstances is the author responsible for the proper functioning
+ * of this software, nor does the author assume any responsibility
+ * for damages incurred with its use.
+ */
+
+/*
+ * Modified for Allied-Telesis RE1000 series.
+ */
+
+
+/*
+ * TODO:
+ * o To support MBH10304 PC card. It is another MB8696x based
+ * PCMCIA Ethernet card by Fujitsu, which is not compatible with
+ * MBH10302.
+ * o To merge FreeBSD(98) efforts into a single source file.
+ * o To support ISA PnP auto configuration for FMV-183/184.
+ * o To reconsider mbuf usage.
+ * o To reconsider transmission buffer usage, including
+ * transmission buffer size (currently 4KB x 2) and pros-and-
+ * cons of multiple frame transmission.
+ * o To test IPX codes.
+ */
+
+#include "fe.h"
+#include "bpfilter.h"
+#include "opt_inet.h"
+#include "opt_ipx.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+
+#include <net/if.h>
+#include <net/if_dl.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#endif
+
+/* IPX code is not tested. FIXME. */
+#ifdef IPX
+#include <netipx/ipx.h>
+#include <netipx/ipx_if.h>
+#endif
+
+/* To be used with IPv6 package of INRIA. */
+#ifdef INET6
+/* IPv6 added by shin 96.2.6 */
+#include <netinet/if_ether6.h>
+#endif
+
+/* XNS code is not tested. FIXME. */
+#ifdef NS
+#include <netns/ns.h>
+#include <netns/ns_if.h>
+#endif
+
+#if NBPFILTER > 0
+#include <net/bpf.h>
+#endif
+
+#include <machine/clock.h>
+
+#include <i386/isa/isa_device.h>
+#include <i386/isa/icu.h>
+
+/* PCCARD suport */
+#include "card.h"
+#if NCARD > 0
+#include <sys/kernel.h>
+#include <sys/select.h>
+#include <pccard/cardinfo.h>
+#include <pccard/slot.h>
+#endif
+
+#include <i386/isa/ic/mb86960.h>
+#include <i386/isa/if_fereg.h>
+
+/*
+ * This version of fe is an ISA device driver.
+ * Override the following macro to adapt it to another bus.
+ * (E.g., PC98.)
+ */
+#define DEVICE struct isa_device
+
+/*
+ * Default settings for fe driver specific options.
+ * They can be set in config file by "options" statements.
+ */
+
+/*
+ * Debug control.
+ * 0: No debug at all. All debug specific codes are stripped off.
+ * 1: Silent. No debug messages are logged except emergent ones.
+ * 2: Brief. Lair events and/or important information are logged.
+ * 3: Detailed. Logs all information which *may* be useful for debugging.
+ * 4: Trace. All actions in the driver is logged. Super verbose.
+ */
+#ifndef FE_DEBUG
+#define FE_DEBUG 1
+#endif
+
+/*
+ * Transmit just one packet per a "send" command to 86960.
+ * This option is intended for performance test. An EXPERIMENTAL option.
+ */
+#ifndef FE_SINGLE_TRANSMISSION
+#define FE_SINGLE_TRANSMISSION 0
+#endif
+
+/*
+ * Device configuration flags.
+ */
+
+/* DLCR6 settings. */
+#define FE_FLAGS_DLCR6_VALUE 0x007F
+
+/* Force DLCR6 override. */
+#define FE_FLAGS_OVERRIDE_DLCR6 0x0080
+
+/* Shouldn't these be defined somewhere else such as isa_device.h? */
+#define NO_IOADDR (-1)
+#define NO_IRQ 0
+
+/*
+ * Data type for a multicast address filter on 8696x.
+ */
+struct fe_filter { u_char data [ FE_FILTER_LEN ]; };
+
+/*
+ * Special filter values.
+ */
+static struct fe_filter const fe_filter_nothing = { FE_FILTER_NOTHING };
+static struct fe_filter const fe_filter_all = { FE_FILTER_ALL };
+
+/* How many registers does an fe-supported adapter have at maximum? */
+#define MAXREGISTERS 32
+
+/*
+ * fe_softc: per line info and status
+ */
+static struct fe_softc {
+
+ /* Used by "common" codes. */
+ struct arpcom arpcom; /* Ethernet common */
+
+ /* Used by config codes. */
+
+ /* Set by probe() and not modified in later phases. */
+ char * typestr; /* printable name of the interface. */
+ u_short iobase; /* base I/O address of the adapter. */
+ u_short ioaddr [ MAXREGISTERS ]; /* I/O addresses of register. */
+ u_short txb_size; /* size of TX buffer, in bytes */
+ u_char proto_dlcr4; /* DLCR4 prototype. */
+ u_char proto_dlcr5; /* DLCR5 prototype. */
+ u_char proto_dlcr6; /* DLCR6 prototype. */
+ u_char proto_dlcr7; /* DLCR7 prototype. */
+ u_char proto_bmpr13; /* BMPR13 prototype. */
+ u_char proto_bmpr14; /* BMPR14 prototype. */
+
+ /* Vendor specific hooks. */
+ void ( * init )( struct fe_softc * ); /* Just before fe_init(). */
+ void ( * stop )( struct fe_softc * ); /* Just after fe_stop(). */
+
+ /* Transmission buffer management. */
+ u_short txb_free; /* free bytes in TX buffer */
+ u_char txb_count; /* number of packets in TX buffer */
+ u_char txb_sched; /* number of scheduled packets */
+
+ /* Excessive collision counter (see fe_tint() for details. */
+ u_char tx_excolls; /* # of excessive collisions. */
+
+ /* Multicast address filter management. */
+ u_char filter_change; /* MARs must be changed ASAP. */
+ struct fe_filter filter;/* new filter value. */
+
+} fe_softc[NFE];
+
+#define sc_if arpcom.ac_if
+#define sc_unit arpcom.ac_if.if_unit
+#define sc_enaddr arpcom.ac_enaddr
+
+/* Standard driver entry points. These can be static. */
+static int fe_probe ( struct isa_device * );
+static int fe_attach ( struct isa_device * );
+static void fe_init ( int );
+static int fe_ioctl ( struct ifnet *, u_long, caddr_t );
+static void fe_start ( struct ifnet * );
+static void fe_reset ( int );
+static void fe_watchdog ( struct ifnet * );
+
+/* Local functions. Order of declaration is confused. FIXME. */
+#ifdef PC98
+static int fe_probe_re1000 ( DEVICE *, struct fe_softc * );
+static int fe_probe_re1000p( DEVICE *, struct fe_softc * );
+static int fe_probe_cnet9ne ( DEVICE *, struct fe_softc * );
+static int fe_probe_cnet98p2( DEVICE *, struct fe_softc * );
+#else
+static int fe_probe_fmv ( DEVICE *, struct fe_softc * );
+static int fe_probe_ati ( DEVICE *, struct fe_softc * );
+static void fe_init_ati ( struct fe_softc * );
+#endif /* PC98 */
+static int fe_probe_gwy ( DEVICE *, struct fe_softc * );
+#if NCARD > 0
+static int fe_probe_mbh ( DEVICE *, struct fe_softc * );
+static void fe_init_mbh ( struct fe_softc * );
+static int fe_probe_tdk ( DEVICE *, struct fe_softc * );
+#endif
+static int fe_get_packet ( struct fe_softc *, u_short );
+static void fe_stop ( int );
+static void fe_tint ( struct fe_softc *, u_char );
+static void fe_rint ( struct fe_softc *, u_char );
+static void fe_xmit ( struct fe_softc * );
+static void fe_emptybuffer ( struct fe_softc * );
+static void fe_write_mbufs ( struct fe_softc *, struct mbuf * );
+static struct fe_filter
+ fe_mcaf ( struct fe_softc * );
+static int fe_hash ( u_char * );
+static void fe_setmode ( struct fe_softc * );
+static void fe_loadmar ( struct fe_softc * );
+#if FE_DEBUG >= 1
+static void fe_dump ( int, struct fe_softc *, char * );
+#endif
+
+/* Driver struct used in the config code. This must be public (external.) */
+struct isa_driver fedriver =
+{
+ fe_probe,
+ fe_attach,
+ "fe",
+ 1 /* It's safe to mark as "sensitive" */
+};
+
+/*
+ * Fe driver specific constants which relate to 86960/86965.
+ */
+
+/* Interrupt masks */
+#define FE_TMASK ( FE_D2_COLL16 | FE_D2_TXDONE )
+#define FE_RMASK ( FE_D3_OVRFLO | FE_D3_CRCERR \
+ | FE_D3_ALGERR | FE_D3_SRTPKT | FE_D3_PKTRDY )
+
+/* Maximum number of iterations for a receive interrupt. */
+#define FE_MAX_RECV_COUNT ( ( 65536 - 2048 * 2 ) / 64 )
+ /*
+ * Maximum size of SRAM is 65536,
+ * minimum size of transmission buffer in fe is 2x2KB,
+ * and minimum amount of received packet including headers
+ * added by the chip is 64 bytes.
+ * Hence FE_MAX_RECV_COUNT is the upper limit for number
+ * of packets in the receive buffer.
+ */
+
+/*
+ * Routines to access contiguous I/O ports.
+ */
+
+static void
+inblk ( struct fe_softc * sc, int offs, u_char * mem, int len )
+{
+ while ( --len >= 0 ) {
+ *mem++ = inb( sc->ioaddr[ offs++ ] );
+ }
+}
+
+static void
+outblk ( struct fe_softc * sc, int offs, u_char const * mem, int len )
+{
+ while ( --len >= 0 ) {
+ outb( sc->ioaddr[ offs++ ], *mem++ );
+ }
+}
+
+/* PCCARD Support */
+#if NCARD > 0
+/*
+ * PC-Card (PCMCIA) specific code.
+ */
+static int feinit ( struct pccard_devinfo * );
+static void feunload ( struct pccard_devinfo * );
+static int fe_card_intr ( struct pccard_devinfo * );
+
+static struct pccard_device fe_info = {
+ "fe",
+ feinit,
+ feunload,
+ fe_card_intr,
+ 0, /* Attributes - presently unused */
+ &net_imask /* XXX - Should this also include tty_imask? */
+};
+
+DATA_SET(pccarddrv_set, fe_info);
+
+/*
+ * Initialize the device - called from Slot manager.
+ */
+static int
+feinit(struct pccard_devinfo *devi)
+{
+ struct fe_softc *sc;
+
+ /* validate unit number. */
+ if (devi->isahd.id_unit >= NFE)
+ return (ENODEV);
+ /*
+ * Probe the device. If a value is returned,
+ * the device was found at the location.
+ */
+#if FE_DEBUG >= 2
+ printf("Start Probe\n");
+#endif
+ /* Initialize "minimum" parts of our softc. */
+ sc = &fe_softc[devi->isahd.id_unit];
+ sc->sc_unit = devi->isahd.id_unit;
+ sc->iobase = devi->isahd.id_iobase;
+
+ /* Use Ethernet address got from CIS, if one is available. */
+ if ((devi->misc[0] & 0x03) == 0x00
+ && (devi->misc[0] | devi->misc[1] | devi->misc[2]) != 0) {
+ /* Yes, it looks like a valid Ether address. */
+ bcopy(devi->misc, sc->sc_enaddr, ETHER_ADDR_LEN);
+ } else {
+ /* Indicate we have no Ether address in CIS. */
+ bzero(sc->sc_enaddr, ETHER_ADDR_LEN);
+ }
+
+ /* Probe supported PC card models. */
+ if (fe_probe_tdk(&devi->isahd, sc) == 0 &&
+ fe_probe_mbh(&devi->isahd, sc) == 0)
+ return (ENXIO);
+#if FE_DEBUG >= 2
+ printf("Start attach\n");
+#endif
+ if (fe_attach(&devi->isahd) == 0)
+ return (ENXIO);
+
+ return (0);
+}
+
+/*
+ * feunload - unload the driver and clear the table.
+ * XXX TODO:
+ * This is usually called when the card is ejected, but
+ * can be caused by a modunload of a controller driver.
+ * The idea is to reset the driver's view of the device
+ * and ensure that any driver entry points such as
+ * read and write do not hang.
+ */
+static void
+feunload(struct pccard_devinfo *devi)
+{
+ struct fe_softc *sc = &fe_softc[devi->isahd.id_unit];
+ printf("fe%d: unload\n", devi->isahd.id_unit);
+ fe_stop(devi->isahd.id_unit);
+}
+
+/*
+ * fe_card_intr - Shared interrupt called from
+ * front end of PC-Card handler.
+ */
+static int
+fe_card_intr(struct pccard_devinfo *devi)
+{
+ feintr(devi->isahd.id_unit);
+ return (1);
+}
+#endif /* NCARD > 0 */
+
+
+/*
+ * Hardware probe routines.
+ */
+
+/* How and where to probe; to support automatic I/O address detection. */
+struct fe_probe_list
+{
+ int ( * probe ) ( DEVICE *, struct fe_softc * );
+ u_short const * addresses;
+};
+
+/* Lists of possible addresses. */
+#ifdef PC98
+static u_short const fe_re1000_addr [] =
+ { 0x0D0, 0x0D2, 0x0D4, 0x0D6, 0x0D8, 0x0DA, 0x0DC, 0x0DE,
+ 0x1D0, 0x1D2, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0x1DC, 0x1DE, 0 };
+static u_short const fe_re1000p_addr [] =
+ { 0x0D0, 0x0D2, 0x0D4, 0x0D8, 0x1D4, 0x1D6, 0x1D8, 0x1DA, 0 };
+static u_short const fe_cnet9ne_addr [] =
+ { 0x73D0, 0 };
+static u_short const fe_cnet98p2_addr [] =
+ { 0x03D0, 0x13D0, 0x23D0, 0x33D0, 0x43D0, 0x53D0, 0x63D0,
+ 0x73D0, 0x83D0, 0x93D0, 0xA3D0, 0xB3D0, 0xC3D0, 0xD3D0, 0 };
+#else
+static u_short const fe_fmv_addr [] =
+ { 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x300, 0x340, 0 };
+static u_short const fe_ati_addr [] =
+ { 0x240, 0x260, 0x280, 0x2A0, 0x300, 0x320, 0x340, 0x380, 0 };
+#endif
+
+static struct fe_probe_list const fe_probe_list [] =
+{
+#ifdef PC98
+ { fe_probe_re1000, fe_re1000_addr },
+ { fe_probe_re1000p, fe_re1000p_addr },
+ /* XXX: We must probe C-NET(98)P2 after C-NET(9N)E. */
+ { fe_probe_cnet9ne, fe_cnet9ne_addr },
+ { fe_probe_cnet98p2, fe_cnet98p2_addr },
+#else
+ { fe_probe_fmv, fe_fmv_addr },
+ { fe_probe_ati, fe_ati_addr },
+#endif
+ { fe_probe_gwy, NULL }, /* GWYs cannot be auto detected. */
+ { NULL, NULL }
+};
+
+
+/*
+ * Determine if the device is present
+ *
+ * on entry:
+ * a pointer to an isa_device struct
+ * on exit:
+ * zero if device not found
+ * or number of i/o addresses used (if found)
+ */
+
+static int
+fe_probe ( DEVICE * dev )
+{
+ struct fe_softc * sc;
+ int u;
+ int nports;
+ struct fe_probe_list const * list;
+ u_short const * addr;
+ u_short single [ 2 ];
+
+ /* Initialize "minimum" parts of our softc. */
+ sc = &fe_softc[ dev->id_unit ];
+ sc->sc_unit = dev->id_unit;
+
+ /* TODO: Should be in each probe routines */
+ sc->proto_bmpr14 = 0;
+
+ /* Probe each possibility, one at a time. */
+ for ( list = fe_probe_list; list->probe != NULL; list++ ) {
+
+ if ( dev->id_iobase != NO_IOADDR ) {
+ /* Probe one specific address. */
+ single[ 0 ] = dev->id_iobase;
+ single[ 1 ] = 0;
+ addr = single;
+ } else if ( list->addresses != NULL ) {
+ /* Auto detect. */
+ addr = list->addresses;
+ } else {
+ /* We need a list of addresses to do auto detect. */
+ continue;
+ }
+
+ /* Probe all possible addresses for the board. */
+ while ( *addr != 0 ) {
+
+ /* See if the address is already in use. */
+ for ( u = 0; u < NFE; u++ ) {
+ if ( fe_softc[u].iobase == *addr ) break;
+ }
+
+#if FE_DEBUG >= 3
+ if ( u == NFE ) {
+ log( LOG_INFO, "fe%d: probing %d at 0x%x\n",
+ sc->sc_unit, list - fe_probe_list, *addr );
+ } else if ( u == sc->sc_unit ) {
+ log( LOG_INFO, "fe%d: re-probing %d at 0x%x?\n",
+ sc->sc_unit, list - fe_probe_list, *addr );
+ } else {
+ log( LOG_INFO, "fe%d: skipping %d at 0x%x\n",
+ sc->sc_unit, list - fe_probe_list, *addr );
+ }
+#endif
+
+ /* Probe the address if it is free. */
+ if ( u == NFE || u == sc->sc_unit ) {
+
+ /* Probe an address. */
+ sc->iobase = *addr;
+ nports = list->probe( dev, sc );
+ if ( nports > 0 ) {
+ /* Found. */
+ dev->id_iobase = *addr;
+ return ( nports );
+ }
+ sc->iobase = 0;
+ }
+
+ /* Try next. */
+ addr++;
+ }
+ }
+
+ /* Probe failed. */
+ return ( 0 );
+}
+
+/*
+ * Check for specific bits in specific registers have specific values.
+ */
+struct fe_simple_probe_struct
+{
+ u_char port; /* Offset from the base I/O address. */
+ u_char mask; /* Bits to be checked. */
+ u_char bits; /* Values to be compared against. */
+};
+
+static int
+fe_simple_probe ( struct fe_softc const * sc,
+ struct fe_simple_probe_struct const * sp )
+{
+ struct fe_simple_probe_struct const * p;
+
+ for ( p = sp; p->mask != 0; p++ ) {
+#if FE_DEBUG >=2
+ printf("Probe Port:%x,Value:%x,Mask:%x.Bits:%x\n",
+ p->port,inb(sc->ioaddr[ p->port]),p->mask,p->bits);
+#endif
+ if ( ( inb( sc->ioaddr[ p->port ] ) & p->mask ) != p->bits )
+ {
+ return ( 0 );
+ }
+ }
+ return ( 1 );
+}
+
+/*
+ * Routines to read all bytes from the config EEPROM through MB86965A.
+ * I'm not sure what exactly I'm doing here... I was told just to follow
+ * the steps, and it worked. Could someone tell me why the following
+ * code works? (Or, why all similar codes I tried previously doesn't
+ * work.) FIXME.
+ */
+
+static void
+fe_strobe_eeprom ( u_short bmpr16 )
+{
+ /*
+ * We must guarantee 800ns (or more) interval to access slow
+ * EEPROMs. The following redundant code provides enough
+ * delay with ISA timing. (Even if the bus clock is "tuned.")
+ * Some modification will be needed on faster busses.
+ */
+ outb( bmpr16, FE_B16_SELECT );
+ outb( bmpr16, FE_B16_SELECT );
+ outb( bmpr16, FE_B16_SELECT | FE_B16_CLOCK );
+ outb( bmpr16, FE_B16_SELECT | FE_B16_CLOCK );
+ outb( bmpr16, FE_B16_SELECT );
+ outb( bmpr16, FE_B16_SELECT );
+}
+
+static void
+fe_read_eeprom ( struct fe_softc * sc, u_char * data )
+{
+ u_short bmpr16 = sc->ioaddr[ FE_BMPR16 ];
+ u_short bmpr17 = sc->ioaddr[ FE_BMPR17 ];
+ u_char n, val, bit;
+
+ /* Read bytes from EEPROM; two bytes per an iteration. */
+ for ( n = 0; n < FE_EEPROM_SIZE / 2; n++ ) {
+
+ /* Reset the EEPROM interface. */
+ outb( bmpr16, 0x00 );
+ outb( bmpr17, 0x00 );
+
+ /* Start EEPROM access. */
+ outb( bmpr16, FE_B16_SELECT );
+ outb( bmpr17, FE_B17_DATA );
+ fe_strobe_eeprom( bmpr16 );
+
+ /* Pass the iteration count to the chip. */
+ val = 0x80 | n;
+ for ( bit = 0x80; bit != 0x00; bit >>= 1 ) {
+ outb( bmpr17, ( val & bit ) ? FE_B17_DATA : 0 );
+ fe_strobe_eeprom( bmpr16 );
+ }
+ outb( bmpr17, 0x00 );
+
+ /* Read a byte. */
+ val = 0;
+ for ( bit = 0x80; bit != 0x00; bit >>= 1 ) {
+ fe_strobe_eeprom( bmpr16 );
+ if ( inb( bmpr17 ) & FE_B17_DATA ) {
+ val |= bit;
+ }
+ }
+ *data++ = val;
+
+ /* Read one more byte. */
+ val = 0;
+ for ( bit = 0x80; bit != 0x00; bit >>= 1 ) {
+ fe_strobe_eeprom( bmpr16 );
+ if ( inb( bmpr17 ) & FE_B17_DATA ) {
+ val |= bit;
+ }
+ }
+ *data++ = val;
+ }
+
+ /* Reset the EEPROM interface, again. */
+ outb( bmpr16, 0x00 );
+ outb( bmpr17, 0x00 );
+
+#if FE_DEBUG >= 3
+ /* Report what we got. */
+ data -= FE_EEPROM_SIZE;
+ log( LOG_INFO, "fe%d: EEPROM:"
+ " %02x%02x%02x%02x %02x%02x%02x%02x -"
+ " %02x%02x%02x%02x %02x%02x%02x%02x -"
+ " %02x%02x%02x%02x %02x%02x%02x%02x -"
+ " %02x%02x%02x%02x %02x%02x%02x%02x\n",
+ sc->sc_unit,
+ data[ 0], data[ 1], data[ 2], data[ 3],
+ data[ 4], data[ 5], data[ 6], data[ 7],
+ data[ 8], data[ 9], data[10], data[11],
+ data[12], data[13], data[14], data[15],
+ data[16], data[17], data[18], data[19],
+ data[20], data[21], data[22], data[23],
+ data[24], data[25], data[26], data[27],
+ data[28], data[29], data[30], data[31] );
+#endif
+}
+
+/*
+ * Hardware (vendor) specific probe routines.
+ */
+
+#ifdef PC98
+/*
+ * Probe and initialization for Allied-Telesis RE1000 series.
+ */
+static int
+fe_probe_re1000 ( DEVICE * isa_dev, struct fe_softc * sc )
+{
+ int i, n;
+ int dlcr6, dlcr7;
+ u_char c = 0;
+
+ static u_short const irqmap [ 4 ] =
+ { IRQ3, IRQ5, IRQ6, IRQ12 };
+
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: probe (0x%x) for RE1000\n", sc->sc_unit, sc->iobase );
+ fe_dump( LOG_INFO, sc, NULL );
+#endif
+
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + (i/2)*0x200 + (i%2);
+ }
+
+ /*
+ * RE1000 does not use 86965 EEPROM interface.
+ */
+ c ^= sc->sc_enaddr[0] = inb(sc->ioaddr[FE_RE1000_MAC0]);
+ c ^= sc->sc_enaddr[1] = inb(sc->ioaddr[FE_RE1000_MAC1]);
+ c ^= sc->sc_enaddr[2] = inb(sc->ioaddr[FE_RE1000_MAC2]);
+ c ^= sc->sc_enaddr[3] = inb(sc->ioaddr[FE_RE1000_MAC3]);
+ c ^= sc->sc_enaddr[4] = inb(sc->ioaddr[FE_RE1000_MAC4]);
+ c ^= sc->sc_enaddr[5] = inb(sc->ioaddr[FE_RE1000_MAC5]);
+ c ^= inb(sc->ioaddr[FE_RE1000_MACCHK]);
+ if (c != 0) return 0;
+
+ if ( sc->sc_enaddr[ 0 ] != 0x00
+ || sc->sc_enaddr[ 1 ] != 0x00
+ || sc->sc_enaddr[ 2 ] != 0xF4 ) return 0;
+
+ /*
+ * check interrupt configure
+ */
+ for (n=0; n<4; n++) {
+ if (isa_dev->id_irq == irqmap[n]) break;
+ }
+ if (n == 4) return 0;
+
+ /*
+ * set irq
+ */
+ c = inb(sc->ioaddr[FE_RE1000_IRQCONF]);
+ c &= (~ FE_RE1000_IRQCONF_IRQ);
+ c |= (1 << (n + FE_RE1000_IRQCONF_IRQSHIFT));
+ outb(sc->ioaddr[FE_RE1000_IRQCONF], c);
+
+ sc->typestr = "RE1000";
+
+ /*
+ * Program the 86965 as follows:
+ * SRAM: 32KB, 100ns, byte-wide access.
+ * Transmission buffer: 4KB x 2.
+ * System bus interface: 16 bits.
+ */
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
+ sc->proto_dlcr5 = 0;
+ sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
+ | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "RE1000 found" );
+#endif
+
+ /* Initialize 86965. */
+ outb( sc->ioaddr[FE_DLCR6], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY(200);
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[FE_DLCR2], 0 );
+ outb( sc->ioaddr[FE_DLCR3], 0 );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "end of fe_probe_re1000()" );
+#endif
+
+ /*
+ * That's all. RE1000 occupies 2*16 I/O addresses, by the way.
+ */
+ return 2; /* ??? */
+}
+
+/*
+ * Probe and initialization for Allied-Telesis RE1000Plus/ME1500 series.
+ */
+static int
+fe_probe_re1000p ( DEVICE * isa_dev, struct fe_softc * sc )
+{
+ int i, n, signature;
+ int dlcr6, dlcr7;
+ u_char eeprom [ FE_EEPROM_SIZE ];
+
+ static u_short const irqmap [ 4 ] =
+ { IRQ3, IRQ5, IRQ6, IRQ12 };
+ static struct fe_simple_probe_struct const probe_signature1 [] = {
+ { FE_DLCR0, 0xBF, 0x00 },
+ { FE_DLCR2, 0xFF, 0x00 },
+ { FE_DLCR4, 0x0F, 0x06 },
+ { FE_DLCR6, 0x0F, 0x06 },
+ { 0 }
+ };
+ static struct fe_simple_probe_struct const probe_signature2 [] = {
+ { FE_DLCR1, 0xFF, 0x00 },
+ { FE_DLCR3, 0xFF, 0x00 },
+ { FE_DLCR5, 0xFF, 0x41 },
+ { 0 }
+ };
+ static struct fe_simple_probe_struct const probe_table [] = {
+ { FE_DLCR2, 0x71, 0x00 },
+ { FE_DLCR4, 0x08, 0x00 },
+ { FE_DLCR5, 0x80, 0x00 },
+ { 0 }
+ };
+ static struct fe_simple_probe_struct const vendor_code [] = {
+ { FE_DLCR8, 0xFF, 0x00 },
+ { FE_DLCR9, 0xFF, 0x00 },
+ { FE_DLCR10, 0xFF, 0xF4 },
+ { 0 }
+ };
+
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: probe (0x%x) for RE1000Plus/ME1500\n", sc->sc_unit, sc->iobase );
+ fe_dump( LOG_INFO, sc, NULL );
+#endif
+
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < 16; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + (i/2)*0x200 + (i%2);
+ }
+ for ( i = 16; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + i*0x200 - 0x1000;
+ }
+
+ /* First, check the "signature" */
+ signature = 0;
+ if (fe_simple_probe(sc, probe_signature1)) {
+ outb(sc->ioaddr[FE_DLCR6], (inb(sc->ioaddr[FE_DLCR6]) & 0xCF) | 0x16);
+ if (fe_simple_probe(sc, probe_signature2))
+ signature = 1;
+ }
+
+ /*
+ * If the "signature" not detected, 86965 *might* be previously
+ * initialized. So, check the Ethernet address here.
+ *
+ * Allied-Telesis uses 00 00 F4 ?? ?? ??.
+ */
+ if (signature == 0) {
+ /* Simple check */
+ if (!fe_simple_probe(sc, probe_table)) return 0;
+
+ /* Disable DLC */
+ dlcr6 = inb(sc->ioaddr[FE_DLCR6]);
+ outb(sc->ioaddr[FE_DLCR6], dlcr6 | FE_D6_DLC_DISABLE);
+ /* Select register bank for DLCR */
+ dlcr7 = inb(sc->ioaddr[FE_DLCR7]);
+ outb(sc->ioaddr[FE_DLCR7], dlcr7 & 0xF3 | FE_D7_RBS_DLCR);
+
+ /* Check the Ethernet address */
+ if (!fe_simple_probe(sc, vendor_code)) return 0;
+
+ /* Restore configuration registers */
+ DELAY(200);
+ outb(sc->ioaddr[FE_DLCR6], dlcr6);
+ outb(sc->ioaddr[FE_DLCR7], dlcr7);
+ }
+
+ /*
+ * We are now almost sure we have an 86965 at the given
+ * address. So, read EEPROM through 86965. We have to write
+ * into LSI registers to read from EEPROM. I want to avoid it
+ * at this stage, but I cannot test the presense of the chip
+ * any further without reading EEPROM. FIXME.
+ */
+ fe_read_eeprom( sc, eeprom );
+
+ /* Make sure that config info in EEPROM and 86965 agree. */
+ if ( eeprom[ FE_EEPROM_CONF ] != inb( sc->ioaddr[FE_BMPR19] ) ) {
+ return 0;
+ }
+
+ /*
+ * Initialize constants in the per-line structure.
+ */
+
+ /* Get our station address from EEPROM. */
+ bcopy( eeprom + FE_ATI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
+
+ sc->typestr = "RE1000Plus/ME1500";
+
+ /*
+ * Read IRQ configuration.
+ */
+ n = (inb(sc->ioaddr[FE_BMPR19]) & FE_B19_IRQ ) >> FE_B19_IRQ_SHIFT;
+ isa_dev->id_irq = irqmap[n];
+
+ /*
+ * Program the 86965 as follows:
+ * SRAM: 32KB, 100ns, byte-wide access.
+ * Transmission buffer: 4KB x 2.
+ * System bus interface: 16 bits.
+ */
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
+ sc->proto_dlcr5 = 0;
+ sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
+ | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "RE1000Plus/ME1500 found" );
+#endif
+
+ /* Initialize 86965. */
+ outb( sc->ioaddr[FE_DLCR6], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY(200);
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[FE_DLCR2], 0 );
+ outb( sc->ioaddr[FE_DLCR3], 0 );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "end of fe_probe_re1000p()" );
+#endif
+
+ /*
+ * That's all. RE1000Plus/ME1500 occupies 2*16 I/O addresses, by the way.
+ */
+ return 2; /* ??? */
+}
+
+/*
+ * Probe and initialization for Contec C-NET(9N)E series.
+ */
+
+/* TODO: Should be in "if_fereg.h" */
+#define FE_CNET9NE_INTR 0x10 /* Interrupt Mask? */
+#define FE_CNET9NE_MAC0 0x11 /* Station(MAC) address */
+#define FE_CNET9NE_MAC1 0x13
+#define FE_CNET9NE_MAC2 0x15
+#define FE_CNET9NE_MAC3 0x17
+#define FE_CNET9NE_MAC4 0x19
+#define FE_CNET9NE_MAC5 0x1B
+
+/* TODO: Should be in "ic/mb86960.h" */
+#define FE_D7_ENDEC 0xC0 /* Encoder/Decoder mode(86960 only) */
+#define FE_D7_ENDEC_NORMAL_NICE 0x00 /* Normal NICE */
+#define FE_D7_ENDEC_NICE_MONITOR 0x40 /* NICE + Monitor */
+#define FE_D7_ENDEC_BYPASS 0x80 /* Encoder/Decoder Bypass */
+#define FE_D7_ENDEC_TEST 0xC0 /* Encoder/Decoder Test */
+
+static int
+fe_probe_cnet9ne ( DEVICE * isa_dev, struct fe_softc * sc )
+{
+ int i;
+ u_char c;
+
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: probe (0x%x) for C-NET(9N)E\n", sc->sc_unit, sc->iobase );
+#endif
+
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < 16; i++ ) {
+ sc->ioaddr[i] = sc->iobase + i;
+ }
+ for ( ; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[i] = sc->iobase + 0x400 - 16 + i;
+ }
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, NULL );
+#endif
+
+ /* Get our station address from EEPROM. */
+ sc->sc_enaddr[0] = inb( sc->ioaddr[FE_CNET9NE_MAC0] );
+ sc->sc_enaddr[1] = inb( sc->ioaddr[FE_CNET9NE_MAC1] );
+ sc->sc_enaddr[2] = inb( sc->ioaddr[FE_CNET9NE_MAC2] );
+ sc->sc_enaddr[3] = inb( sc->ioaddr[FE_CNET9NE_MAC3] );
+ sc->sc_enaddr[4] = inb( sc->ioaddr[FE_CNET9NE_MAC4] );
+ sc->sc_enaddr[5] = inb( sc->ioaddr[FE_CNET9NE_MAC5] );
+
+#if 1
+ /*
+ * Check the Ethernet address here.
+ *
+ * Contec uses 00 80 4C ?? ?? ??.
+ */
+ if ( sc->sc_enaddr[0] != (u_char)0x00
+ || sc->sc_enaddr[1] != (u_char)0x80
+ || sc->sc_enaddr[2] != (u_char)0x4C ) {
+#else
+ /*
+ * Make sure we got a valid Ethernet address.
+ */
+ if ( ( sc->sc_enaddr[0] & 0x03 ) != 0x00 /* Multicast or Local address. */
+ || ( sc->sc_enaddr[0] | sc->sc_enaddr[1] | sc->sc_enaddr[2] ) == 0x00 ) {
+#endif
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: invalid MAC adrs(%x:%x:%x:%x:%x:%x)\n"
+ , sc->sc_unit
+ , (u_char)sc->sc_enaddr[0], (u_char)sc->sc_enaddr[1]
+ , (u_char)sc->sc_enaddr[2], (u_char)sc->sc_enaddr[3]
+ , (u_char)sc->sc_enaddr[4], (u_char)sc->sc_enaddr[5] );
+#endif
+ return 0;
+ }
+
+ /* See if C-NET(9N)E is on its address. */
+ if ( inb( sc->ioaddr[FE_DLCR6] ) == (u_char)0xff ) {
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: inb(%x) returns 0xff\n"
+ , sc->sc_unit, sc->ioaddr[FE_DLCR6] );
+#endif
+ return 0;
+ }
+
+ sc->typestr = "C-NET9NE";
+
+ /*
+ * Program the 86960 as follows:
+ * SRAM: 64KB, word-wide access.
+ * Transmission buffer: 4KB x 2.
+ * System bus interface: 16 bits.
+ * Encoder/Decoder mode: Normal NICE.
+ *
+ * 86960 manual says that SRAM access-time can't be configured.
+ * (must be 1)
+ */
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL;
+ sc->proto_dlcr5 = FE_D5_RMTRST; /* reserved bit(must be 1) */
+ sc->proto_dlcr6 = FE_D6_BUFSIZ_64KB | FE_D6_TXBSIZ_2x4KB
+ | FE_D6_BBW_WORD | FE_D6_SBW_WORD | FE_D6_SRAM;
+#ifndef CNET9NC
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_ENDEC_NORMAL_NICE;
+#else
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_ENDEC_BYPASS;
+#endif
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
+ sc->proto_bmpr14 = 0;
+
+ sc->stop = sc->init = NULL;
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "C-NET(9N)E found" );
+#endif
+
+ /* Initialize 86960. */
+ outb( sc->ioaddr[FE_DLCR6], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+#if 1 /* XXX: Is this really necessary? FIXME. */
+ c = inb( sc->ioaddr[FE_DLCR1] );
+ if ( c == (u_char)0xff ) {
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: inb(%x) returns 0xff\n"
+ , sc->sc_unit, sc->ioaddr[FE_DLCR1] );
+#endif
+ return 0;
+ }
+ if ( ( c & FE_D1_PKTRDY ) == 0 ) {
+ outb( sc->ioaddr[FE_DLCR1], FE_D1_PKTRDY );
+ }
+#endif
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[FE_DLCR2], 0 );
+ outb( sc->ioaddr[FE_DLCR3], 0 );
+
+#ifndef CNET9NC
+ /* Enable interrupt? FIXME. */
+ outb( sc->ioaddr[FE_CNET9NE_INTR], 0x10 );
+#endif
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "end of fe_probe_cnet9ne()" );
+#endif
+
+ /*
+ * XXX: The I/O address range is fragmented in the CNET(9N)E.
+ * "16" is the number of regs at iobase.
+ */
+ return 16;
+}
+
+/*
+ * Probe and initialization for Contec C-NET(98)P2 series.
+ */
+
+/*
+ * Routines to read all bytes from the config EEPROM through TDK 78Q8377A.
+ * I'm not sure what exactly I'm doing here... I was told just to follow
+ * the steps, and it worked. Could someone tell me why the following
+ * code works? FIXME.
+ */
+
+static void
+fe_strobe_eeprom_tdk ( u_short bmpr12 )
+{
+ outb( bmpr12, 0x10 );
+ outb( bmpr12, 0x12 );
+ outb( bmpr12, 0x12 );
+ outb( bmpr12, 0x16 );
+ outb( bmpr12, 0x12 | 0x01 );
+ outb( bmpr12, 0x16 | 0x01 );
+ outb( bmpr12, 0x12 | 0x01 );
+ outb( bmpr12, 0x16 | 0x01 );
+ outb( bmpr12, 0x12 );
+ outb( bmpr12, 0x16 );
+}
+
+static void
+fe_read_eeprom_tdk ( struct fe_softc * sc, u_char * data )
+{
+ u_short bmpr12 = sc->ioaddr[FE_DLCR12];
+ u_char n, val, bit;
+
+ outb( sc->ioaddr[FE_DLCR6], FE_D6_BBW_WORD | FE_D6_SBW_WORD
+ | FE_D6_DLC_DISABLE );
+ outb( sc->ioaddr[FE_DLCR7], FE_D7_BYTSWP_LH | FE_D7_RBS_BMPR
+ | FE_D7_RDYPNS | FE_D7_POWER_UP );
+
+ /* Read bytes from EEPROM; two bytes per an iteration. */
+ for ( n = 0; n < FE_EEPROM_SIZE / 2; n++ ) {
+
+ /* Start EEPROM access. */
+ fe_strobe_eeprom_tdk( bmpr12 );
+
+ /* Pass the iteration count to the chip. */
+ for ( bit = 0x80; bit != 0x00; bit >>= 1 ) {
+ val = ( n & bit ) ? 0x01 : 0x00;
+ outb( bmpr12, 0x12 | val );
+ outb( bmpr12, 0x16 | val );
+ }
+
+ /* Read a byte. */
+ val = 0;
+ for ( bit = 0x80; bit != 0x00; bit >>= 1 ) {
+ outb( bmpr12, 0x12 );
+ outb( bmpr12, 0x16 );
+ if ( inb( bmpr12 ) & 0x01 ) {
+ val |= bit;
+ }
+ }
+ *data++ = val;
+
+ /* Read one more byte. */
+ val = 0;
+ for ( bit = 0x80; bit != 0x00; bit >>= 1 ) {
+ outb( bmpr12, 0x12 );
+ outb( bmpr12, 0x16 );
+ if ( inb( bmpr12 ) & 0x01 ) {
+ val |= bit;
+ }
+ }
+ *data++ = val;
+
+ outb( bmpr12, 0x10 );
+ }
+
+ /* Reset the EEPROM interface. */
+ outb( bmpr12, 0x00 );
+
+#if FE_DEBUG >= 3
+ /* Report what we got. */
+ data -= FE_EEPROM_SIZE;
+ log( LOG_INFO, "fe%d: EEPROM:"
+ " %02x%02x%02x%02x %02x%02x%02x%02x -"
+ " %02x%02x%02x%02x %02x%02x%02x%02x -"
+ " %02x%02x%02x%02x %02x%02x%02x%02x -"
+ " %02x%02x%02x%02x %02x%02x%02x%02x\n",
+ sc->sc_unit,
+ data[ 0], data[ 1], data[ 2], data[ 3],
+ data[ 4], data[ 5], data[ 6], data[ 7],
+ data[ 8], data[ 9], data[10], data[11],
+ data[12], data[13], data[14], data[15],
+ data[16], data[17], data[18], data[19],
+ data[20], data[21], data[22], data[23],
+ data[24], data[25], data[26], data[27],
+ data[28], data[29], data[30], data[31] );
+#endif
+}
+
+/* TODO: Should be in "if_fereg.h" */
+#define FE_CNET98P2_EEP_IRQ (0x04 * 2 + 1) /* Irq */
+#define FE_CNET98P2_EEP_ADDR (0x08 * 2) /* Station(MAC) address */
+#define FE_CNET98P2_EEP_DUPLEX (0x0c * 2 + 1) /* Duplex mode */
+
+static int
+fe_probe_cnet98p2 ( DEVICE * isa_dev, struct fe_softc * sc )
+{
+ int i;
+ u_char duplex;
+ u_char eeprom[FE_EEPROM_SIZE];
+ static u_short const irqmap [] =
+ /* INT0 INT1 INT2 */
+ { NO_IRQ, NO_IRQ, NO_IRQ, IRQ3, NO_IRQ, IRQ5, IRQ6, NO_IRQ,
+ NO_IRQ, IRQ9, IRQ10, NO_IRQ, IRQ12, IRQ13, NO_IRQ, NO_IRQ };
+ /* INT3 INT4 INT5 INT6 */
+
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: probe (0x%x) for C-NET(98)P2\n", sc->sc_unit, sc->iobase );
+#endif
+
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < 16; i++ ) {
+ sc->ioaddr[i] = sc->iobase + i;
+ }
+ /* Full unused slots with a safe address. */
+ for ( ; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[i] = sc->iobase;
+ }
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, NULL );
+#endif
+
+ /* See if C-NET(98)P2 is on its address. */
+ if ( inb( sc->ioaddr[FE_DLCR0] ) == (u_char)0xff ) {
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: inb(%x) returns 0xff\n"
+ , sc->sc_unit, sc->ioaddr[FE_DLCR0] );
+#endif
+ return 0;
+ }
+ if ( inb( sc->ioaddr[FE_DLCR6] ) == (u_char)0xff ) {
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: inb(%x) returns 0xff\n"
+ , sc->sc_unit, sc->ioaddr[FE_DLCR6] );
+#endif
+ return 0;
+ }
+
+ /*
+ * We are now almost sure we have a 78Q8377 at the given
+ * address. So, read EEPROM through 78Q8377. We have to write
+ * into LSI registers to read from EEPROM. FIXME.
+ */
+ fe_read_eeprom_tdk( sc, eeprom );
+
+ /*
+ * Initialize constants in the per-line structure.
+ */
+
+ /* Get our station address from EEPROM. */
+ bcopy( eeprom + FE_CNET98P2_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
+
+#if 1
+ /*
+ * Check the Ethernet address here.
+ *
+ * Contec uses 00 80 4C ?? ?? ??.
+ */
+ if ( sc->sc_enaddr[0] != (u_char)0x00
+ || sc->sc_enaddr[1] != (u_char)0x80
+ || sc->sc_enaddr[2] != (u_char)0x4C ) {
+#else
+ /*
+ * Make sure we got a valid Ethernet address.
+ */
+ if ( ( sc->sc_enaddr[0] & 0x03 ) != 0x00 /* Multicast or Local address. */
+ || ( sc->sc_enaddr[0] | sc->sc_enaddr[1] | sc->sc_enaddr[2] ) == 0x00 ) {
+#endif
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: invalid MAC adrs(%x:%x:%x:%x:%x:%x)\n"
+ , sc->sc_unit
+ , (u_char)sc->sc_enaddr[0], (u_char)sc->sc_enaddr[1]
+ , (u_char)sc->sc_enaddr[2], (u_char)sc->sc_enaddr[3]
+ , (u_char)sc->sc_enaddr[4], (u_char)sc->sc_enaddr[5] );
+#endif
+ return 0;
+ }
+
+ /*
+ * Get IRQ configuration from EEPROM.
+ */
+ isa_dev->id_irq = irqmap[ eeprom[FE_CNET98P2_EEP_IRQ] ];
+ if ( isa_dev->id_irq == NO_IRQ ) {
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: invalid irq configuration(%d)\n"
+ , sc->sc_unit, eeprom[FE_CNET98P2_EEP_IRQ] );
+#endif
+ return 0;
+ }
+
+ /*
+ * Get Duplex-mode configuration from EEPROM.
+ */
+ duplex = eeprom[FE_CNET98P2_EEP_DUPLEX] & FE_D4_DSC;
+ sc->typestr = ( duplex ? "CNET98P2(Full duplex)"
+ : "CNET98P2(Half duplex)" );
+
+ /*
+ * Program the 78Q8377 as follows:
+ * SRAM: 32KB, 100ns, byte-wide access.
+ * Transmission buffer: 4KB x 2.
+ * System bus interface: 16 bits.
+ * XXX: Should we add IDENT_NICE or IDENT_EC to DLCR7? FIXME.
+ */
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL | duplex;
+ sc->proto_dlcr5 = 0;
+ sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
+ | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH;
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
+ sc->proto_bmpr14 = FE_B14_FILTER;
+
+ sc->stop = sc->init = NULL;
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "C-NET(98)P2 found" );
+#endif
+
+ /* Initialize 78Q8377. */
+ outb( sc->ioaddr[FE_DLCR6], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[FE_DLCR2], 0 );
+ outb( sc->ioaddr[FE_DLCR3], 0 );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "end of fe_probe_cnet98p2()" );
+#endif
+
+ /*
+ * That's all. C-NET(98)P2 occupies 16 I/O addresses, as always.
+ */
+ return 16;
+}
+#else
+/*
+ * Probe and initialization for Fujitsu FMV-180 series boards
+ */
+static int
+fe_probe_fmv ( DEVICE * dev, struct fe_softc * sc )
+{
+ int i, n;
+
+ static u_short const baseaddr [ 8 ] =
+ { 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x300, 0x340 };
+ static u_short const irqmap [ 4 ] =
+ { IRQ3, IRQ7, IRQ10, IRQ15 };
+
+ static struct fe_simple_probe_struct const probe_table [] = {
+ { FE_DLCR2, 0x70, 0x00 },
+ { FE_DLCR4, 0x08, 0x00 },
+ /* { FE_DLCR5, 0x80, 0x00 }, Doesn't work. */
+
+ { FE_FMV0, 0x78, 0x50 }, /* ERRDY+PRRDY */
+ { FE_FMV1, 0xB0, 0x00 }, /* FMV-183/184 has 0x48 bits. */
+ { FE_FMV3, 0x7F, 0x00 },
+#if 1
+ /*
+ * Test *vendor* part of the station address for Fujitsu.
+ * The test will gain reliability of probe process, but
+ * it rejects FMV-180 clone boards manufactured by other vendors.
+ * We have to turn the test off when such cards are made available.
+ */
+ { FE_FMV4, 0xFF, 0x00 },
+ { FE_FMV5, 0xFF, 0x00 },
+ { FE_FMV6, 0xFF, 0x0E },
+#else
+ /*
+ * We can always verify the *first* 2 bits (in Ethernet
+ * bit order) are "no multicast" and "no local" even for
+ * unknown vendors.
+ */
+ { FE_FMV4, 0x03, 0x00 },
+#endif
+ { 0 }
+ };
+
+ /* "Hardware revision ID" */
+ int revision;
+
+ /*
+ * See if the specified address is possible for FMV-180 series.
+ */
+ for ( i = 0; i < 8; i++ ) {
+ if ( baseaddr[ i ] == sc->iobase ) break;
+ }
+ if ( i == 8 ) return 0;
+
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + i;
+ }
+
+ /* Simple probe. */
+ if ( !fe_simple_probe( sc, probe_table ) ) return 0;
+
+ /* Check if our I/O address matches config info. on EEPROM. */
+ n = ( inb( sc->ioaddr[ FE_FMV2 ] ) & FE_FMV2_IOS )
+ >> FE_FMV2_IOS_SHIFT;
+ if ( baseaddr[ n ] != sc->iobase ) {
+#if 0
+ /* May not work on some revisions of the cards... FIXME. */
+ return 0;
+#else
+ /* Just log the fact and see what happens... FIXME. */
+ log( LOG_WARNING, "fe%d: strange I/O config?\n", sc->sc_unit );
+#endif
+ }
+
+ /* Find the "hardware revision." */
+ revision = inb( sc->ioaddr[ FE_FMV1 ] ) & FE_FMV1_REV;
+
+ /* Determine the card type. */
+ sc->typestr = NULL;
+ switch ( inb( sc->ioaddr[ FE_FMV0 ] ) & FE_FMV0_MEDIA ) {
+ case 0:
+ /* No interface? This doesn't seem to be an FMV-180... */
+ return 0;
+ case FE_FMV0_MEDIUM_T:
+ switch ( revision ) {
+ case 8:
+ sc->typestr = "FMV-183";
+ break;
+ case 12:
+ sc->typestr = "FMV-183 (on-board)";
+ break;
+ }
+ break;
+ case FE_FMV0_MEDIUM_T | FE_FMV0_MEDIUM_5:
+ switch ( revision ) {
+ case 0:
+ sc->typestr = "FMV-181";
+ break;
+ case 1:
+ sc->typestr = "FMV-181A";
+ break;
+ }
+ break;
+ case FE_FMV0_MEDIUM_2:
+ switch ( revision ) {
+ case 8:
+ sc->typestr = "FMV-184 (CSR = 2)";
+ break;
+ }
+ break;
+ case FE_FMV0_MEDIUM_5:
+ switch ( revision ) {
+ case 8:
+ sc->typestr = "FMV-184 (CSR = 1)";
+ break;
+ }
+ break;
+ case FE_FMV0_MEDIUM_2 | FE_FMV0_MEDIUM_5:
+ switch ( revision ) {
+ case 0:
+ sc->typestr = "FMV-182";
+ break;
+ case 1:
+ sc->typestr = "FMV-182A";
+ break;
+ case 8:
+ sc->typestr = "FMV-184 (CSR = 3)";
+ break;
+ }
+ break;
+ }
+ if ( sc->typestr == NULL ) {
+ /* Unknown card type... Hope the driver works. */
+ sc->typestr = "unknown FMV-180 version";
+ log( LOG_WARNING, "fe%d: %s: %x-%x-%x-%x\n",
+ sc->sc_unit, sc->typestr,
+ inb( sc->ioaddr[ FE_FMV0 ] ),
+ inb( sc->ioaddr[ FE_FMV1 ] ),
+ inb( sc->ioaddr[ FE_FMV2 ] ),
+ inb( sc->ioaddr[ FE_FMV3 ] ) );
+ }
+
+ /*
+ * An FMV-180 has been proved.
+ * Determine which IRQ to be used.
+ *
+ * In this version, we give a priority to the kernel config file.
+ * If the EEPROM and config don't match, say it to the user for
+ * an attention.
+ */
+ n = ( inb( sc->ioaddr[ FE_FMV2 ] ) & FE_FMV2_IRS )
+ >> FE_FMV2_IRS_SHIFT;
+ if ( dev->id_irq == NO_IRQ ) {
+ /* Just use the probed value. */
+ dev->id_irq = irqmap[ n ];
+ } else if ( dev->id_irq != irqmap[ n ] ) {
+ /* Don't match. */
+ log( LOG_WARNING,
+ "fe%d: check IRQ in config; it may be incorrect\n",
+ sc->sc_unit );
+ }
+
+ /*
+ * Initialize constants in the per-line structure.
+ */
+
+ /* Get our station address from EEPROM. */
+ inblk( sc, FE_FMV4, sc->sc_enaddr, ETHER_ADDR_LEN );
+
+ /* Make sure we got a valid station address. */
+ if ( ( sc->sc_enaddr[ 0 ] & 0x03 ) != 0x00
+ || ( sc->sc_enaddr[ 0 ] == 0x00
+ && sc->sc_enaddr[ 1 ] == 0x00
+ && sc->sc_enaddr[ 2 ] == 0x00 ) ) return 0;
+
+ /*
+ * Register values which (may) depend on board design.
+ *
+ * Program the 86960 as follows:
+ * SRAM: 32KB, 100ns, byte-wide access.
+ * Transmission buffer: 4KB x 2.
+ * System bus interface: 16 bits.
+ */
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL;
+ sc->proto_dlcr5 = 0;
+ sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
+ | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
+
+ /*
+ * Minimum initialization of the hardware.
+ * We write into registers; hope I/O ports have no
+ * overlap with other boards.
+ */
+
+ /* Initialize ASIC. */
+ outb( sc->ioaddr[ FE_FMV3 ], 0 );
+ outb( sc->ioaddr[ FE_FMV10 ], 0 );
+
+ /* Initialize 86960. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[ FE_DLCR2 ], 0 );
+ outb( sc->ioaddr[ FE_DLCR3 ], 0 );
+
+ /* "Refresh" hardware configuration. FIXME. */
+ outb( sc->ioaddr[ FE_FMV2 ], inb( sc->ioaddr[ FE_FMV2 ] ) );
+
+ /* Turn the "master interrupt control" flag of ASIC on. */
+ outb( sc->ioaddr[ FE_FMV3 ], FE_FMV3_IRQENB );
+
+ /*
+ * That's all. FMV-180 occupies 32 I/O addresses, by the way.
+ */
+ return 32;
+}
+
+/*
+ * Probe and initialization for Allied-Telesis AT1700/RE2000 series.
+ */
+static int
+fe_probe_ati ( DEVICE * dev, struct fe_softc * sc )
+{
+ int i, n;
+ u_char eeprom [ FE_EEPROM_SIZE ];
+ u_char save16, save17;
+
+ static u_short const baseaddr [ 8 ] =
+ { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300 };
+ static u_short const irqmaps [ 4 ][ 4 ] =
+ {
+ { IRQ3, IRQ4, IRQ5, IRQ9 },
+ { IRQ10, IRQ11, IRQ12, IRQ15 },
+ { IRQ3, IRQ11, IRQ5, IRQ15 },
+ { IRQ10, IRQ11, IRQ14, IRQ15 },
+ };
+ static struct fe_simple_probe_struct const probe_table [] = {
+ { FE_DLCR2, 0x70, 0x00 },
+ { FE_DLCR4, 0x08, 0x00 },
+ { FE_DLCR5, 0x80, 0x00 },
+#if 0
+ { FE_BMPR16, 0x1B, 0x00 },
+ { FE_BMPR17, 0x7F, 0x00 },
+#endif
+ { 0 }
+ };
+
+ /* Assume we have 86965 and no need to restore these. */
+ save16 = 0;
+ save17 = 0;
+
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: probe (0x%x) for ATI\n",
+ sc->sc_unit, sc->iobase );
+ fe_dump( LOG_INFO, sc, NULL );
+#endif
+
+ /*
+ * See if the specified address is possible for MB86965A JLI mode.
+ */
+ for ( i = 0; i < 8; i++ ) {
+ if ( baseaddr[ i ] == sc->iobase ) break;
+ }
+ if ( i == 8 ) goto NOTFOUND;
+
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + i;
+ }
+
+ /*
+ * We should test if MB86965A is on the base address now.
+ * Unfortunately, it is very hard to probe it reliably, since
+ * we have no way to reset the chip under software control.
+ * On cold boot, we could check the "signature" bit patterns
+ * described in the Fujitsu document. On warm boot, however,
+ * we can predict almost nothing about register values.
+ */
+ if ( !fe_simple_probe( sc, probe_table ) ) goto NOTFOUND;
+
+ /* Check if our I/O address matches config info on 86965. */
+ n = ( inb( sc->ioaddr[ FE_BMPR19 ] ) & FE_B19_ADDR )
+ >> FE_B19_ADDR_SHIFT;
+ if ( baseaddr[ n ] != sc->iobase ) goto NOTFOUND;
+
+ /*
+ * We are now almost sure we have an AT1700 at the given
+ * address. So, read EEPROM through 86965. We have to write
+ * into LSI registers to read from EEPROM. I want to avoid it
+ * at this stage, but I cannot test the presence of the chip
+ * any further without reading EEPROM. FIXME.
+ */
+ save16 = inb( sc->ioaddr[ FE_BMPR16 ] );
+ save17 = inb( sc->ioaddr[ FE_BMPR17 ] );
+ fe_read_eeprom( sc, eeprom );
+
+ /* Make sure the EEPROM is turned off. */
+ outb( sc->ioaddr[ FE_BMPR16 ], 0 );
+ outb( sc->ioaddr[ FE_BMPR17 ], 0 );
+
+ /* Make sure that config info in EEPROM and 86965 agree. */
+ if ( eeprom[ FE_EEPROM_CONF ] != inb( sc->ioaddr[ FE_BMPR19 ] ) ) {
+ goto NOTFOUND;
+ }
+
+ /*
+ * The following model identification codes are stolen from
+ * from the NetBSD port of the fe driver. My reviewers
+ * suggested minor revision.
+ */
+
+ /* Determine the card type. */
+ switch (eeprom[FE_ATI_EEP_MODEL]) {
+ case FE_ATI_MODEL_AT1700T:
+ sc->typestr = "AT-1700T/RE2001";
+ break;
+ case FE_ATI_MODEL_AT1700BT:
+ sc->typestr = "AT-1700BT/RE2003";
+ break;
+ case FE_ATI_MODEL_AT1700FT:
+ sc->typestr = "AT-1700FT/RE2009";
+ break;
+ case FE_ATI_MODEL_AT1700AT:
+ sc->typestr = "AT-1700AT/RE2005";
+ break;
+ default:
+ sc->typestr = "unknown AT-1700/RE2000 ?";
+ break;
+ }
+
+ /*
+ * Try to determine IRQ settings.
+ * Different models use different ranges of IRQs.
+ */
+ if ( dev->id_irq == NO_IRQ ) {
+ n = ( inb( sc->ioaddr[ FE_BMPR19 ] ) & FE_B19_IRQ )
+ >> FE_B19_IRQ_SHIFT;
+ switch ( eeprom[ FE_ATI_EEP_REVISION ] & 0xf0 ) {
+ case 0x30:
+ dev->id_irq = irqmaps[ 3 ][ n ];
+ break;
+ case 0x10:
+ case 0x50:
+ dev->id_irq = irqmaps[ 2 ][ n ];
+ break;
+ case 0x40:
+ case 0x60:
+ if ( eeprom[ FE_ATI_EEP_MAGIC ] & 0x04 ) {
+ dev->id_irq = irqmaps[ 1 ][ n ];
+ } else {
+ dev->id_irq = irqmaps[ 0 ][ n ];
+ }
+ break;
+ default:
+ dev->id_irq = irqmaps[ 0 ][ n ];
+ break;
+ }
+ }
+
+
+ /*
+ * Initialize constants in the per-line structure.
+ */
+
+ /* Get our station address from EEPROM. */
+ bcopy( eeprom + FE_ATI_EEP_ADDR, sc->sc_enaddr, ETHER_ADDR_LEN );
+
+#if 1
+ /*
+ * This test doesn't work well for AT1700 look-alike by
+ * other vendors.
+ */
+ /* Make sure the vendor part is for Allied-Telesis. */
+ if ( sc->sc_enaddr[ 0 ] != 0x00
+ || sc->sc_enaddr[ 1 ] != 0x00
+ || sc->sc_enaddr[ 2 ] != 0xF4 ) return 0;
+
+#else
+ /* Make sure we got a valid station address. */
+ if ( ( sc->sc_enaddr[ 0 ] & 0x03 ) != 0x00
+ || ( sc->sc_enaddr[ 0 ] == 0x00
+ && sc->sc_enaddr[ 1 ] == 0x00
+ && sc->sc_enaddr[ 2 ] == 0x00 ) ) return 0;
+#endif
+
+ /*
+ * Program the 86960 as follows:
+ * SRAM: 32KB, 100ns, byte-wide access.
+ * Transmission buffer: 4KB x 2.
+ * System bus interface: 16 bits.
+ */
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL; /* FIXME */
+ sc->proto_dlcr5 = 0;
+ sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
+ | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_EC;
+#if 0 /* XXXX Should we use this? FIXME. */
+ sc->proto_bmpr13 = eeprom[ FE_ATI_EEP_MEDIA ];
+#else
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
+#endif
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "ATI found" );
+#endif
+
+ /* Setup hooks. This may solves a nasty bug. FIXME. */
+ sc->init = fe_init_ati;
+
+ /* Initialize 86965. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[ FE_DLCR2 ], 0 );
+ outb( sc->ioaddr[ FE_DLCR3 ], 0 );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "end of fe_probe_ati()" );
+#endif
+
+ /*
+ * That's all. AT1700 occupies 32 I/O addresses, by the way.
+ */
+ return 32;
+
+ NOTFOUND:
+ /*
+ * We have no AT1700 at a given address.
+ * Restore BMPR16 and BMPR17 if we have destroyed them,
+ * hoping that the hardware on the address didn't get
+ * bad side effect.
+ */
+ if ( save16 != 0 | save17 != 0 ) {
+ outb( sc->ioaddr[ FE_BMPR16 ], save16 );
+ outb( sc->ioaddr[ FE_BMPR17 ], save17 );
+ }
+ return ( 0 );
+}
+
+/* ATI specific initialization routine. */
+static void
+fe_init_ati ( struct fe_softc * sc )
+{
+/*
+ * I've told that the following operation "Resets" the chip.
+ * Hope this solve a bug which hangs up the driver under
+ * heavy load... FIXME.
+ */
+
+ /* Minimal initialization of 86965. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* "Reset" by wrting into an undocument register location. */
+ outb( sc->ioaddr[ 0x1F ], 0 );
+
+ /* How long do we have to wait after the reset? FIXME. */
+ DELAY( 300 );
+}
+#endif /* PC98 */
+
+/*
+ * Probe and initialization for Gateway Communications' old cards.
+ */
+static int
+fe_probe_gwy ( DEVICE * dev, struct fe_softc * sc )
+{
+ int i;
+
+ static struct fe_simple_probe_struct probe_table [] = {
+ { FE_DLCR2, 0x70, 0x00 },
+ { FE_DLCR4, 0x08, 0x00 },
+ { FE_DLCR7, 0xC0, 0x00 },
+ /*
+ * Test *vendor* part of the address for Gateway.
+ * This test is essential to identify Gateway's cards.
+ * We shuld define some symbolic names for the
+ * following offsets. FIXME.
+ */
+ { 0x18, 0xFF, 0x00 },
+ { 0x19, 0xFF, 0x00 },
+ { 0x1A, 0xFF, 0x61 },
+ { 0 }
+ };
+
+ /*
+ * We need explicit IRQ and supported address.
+ * I'm not sure which address and IRQ is possible for Gateway
+ * Ethernet family. The following accepts everything. FIXME.
+ */
+ if ( dev->id_irq == NO_IRQ || ( sc->iobase & ~0x3E0 ) != 0 ) {
+ return ( 0 );
+ }
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "top of probe" );
+#endif
+
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + i;
+ }
+
+ /* See if the card is on its address. */
+ if ( !fe_simple_probe( sc, probe_table ) ) {
+ return 0;
+ }
+
+ /* Determine the card type. */
+ sc->typestr = "Gateway Ethernet w/ Fujitsu chipset";
+
+ /* Get our station address from EEPROM. */
+ inblk( sc, 0x18, sc->sc_enaddr, ETHER_ADDR_LEN );
+
+ /*
+ * Program the 86960 as follows:
+ * SRAM: 16KB, 100ns, byte-wide access.
+ * Transmission buffer: 2KB x 2.
+ * System bus interface: 16 bits.
+ * Make sure to clear out ID bits in DLCR7
+ * (They actually are Encoder/Decoder control in NICE.)
+ */
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL;
+ sc->proto_dlcr5 = 0;
+ sc->proto_dlcr6 = FE_D6_BUFSIZ_16KB | FE_D6_TXBSIZ_2x2KB
+ | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH;
+ sc->proto_bmpr13 = 0;
+
+ /* Minimal initialization of 86960. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[ FE_DLCR2 ], 0 );
+ outb( sc->ioaddr[ FE_DLCR3 ], 0 );
+
+ /* That's all. The card occupies 32 I/O addresses, as always. */
+ return 32;
+}
+
+#if NCARD > 0
+/*
+ * Probe and initialization for Fujitsu MBH10302 PCMCIA Ethernet interface.
+ * Note that this is for 10302 only; MBH10304 is handled by fe_probe_tdk().
+ */
+static int
+fe_probe_mbh ( DEVICE * dev, struct fe_softc * sc )
+{
+ int i,type;
+
+ static struct fe_simple_probe_struct probe_table [] = {
+ { FE_DLCR0, 0x09, 0x00 },
+ { FE_DLCR2, 0x79, 0x00 },
+ { FE_DLCR4, 0x08, 0x00 },
+ { FE_DLCR6, 0xFF, 0xB6 },
+ /*
+ * The following location has the first byte of the card's
+ * Ethernet (MAC) address.
+ * We can always verify the *first* 2 bits (in Ethernet
+ * bit order) are "global" and "unicast" for any vendors'.
+ */
+ { FE_MBH10, 0x03, 0x00 },
+
+ /* Just a gap? Seems reliable, anyway. */
+ { 0x12, 0xFF, 0x00 },
+ { 0x13, 0xFF, 0x00 },
+ { 0x14, 0xFF, 0x00 },
+ { 0x15, 0xFF, 0x00 },
+ { 0x16, 0xFF, 0x00 },
+ { 0x17, 0xFF, 0x00 },
+#if 0
+ { 0x18, 0xFF, 0xFF },
+ { 0x19, 0xFF, 0xFF },
+#endif
+
+ { 0 }
+ };
+
+ /*
+ * We need explicit IRQ and supported address.
+ */
+ if ( dev->id_irq == NO_IRQ || ( sc->iobase & ~0x3E0 ) != 0 ) {
+ return ( 0 );
+ }
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "top of probe" );
+#endif
+
+ /* Setup an I/O address mapping table. */
+ for ( i = 0; i < MAXREGISTERS; i++ ) {
+ sc->ioaddr[ i ] = sc->iobase + i;
+ }
+
+ /*
+ * See if MBH10302 is on its address.
+ * I'm not sure the following probe code works. FIXME.
+ */
+ if ( !fe_simple_probe( sc, probe_table ) ) return 0;
+
+ /* Determine the card type. */
+ sc->typestr = "MBH10302 (PCMCIA)";
+
+ /*
+ * Initialize constants in the per-line structure.
+ */
+
+ /* Get our station address from EEPROM. */
+ inblk( sc, FE_MBH10, sc->sc_enaddr, ETHER_ADDR_LEN );
+
+ /* Make sure we got a valid station address. */
+ if ( sc->sc_enaddr[ 0 ] == 0x00
+ && sc->sc_enaddr[ 1 ] == 0x00
+ && sc->sc_enaddr[ 2 ] == 0x00 ) return 0;
+
+ /*
+ * Program the 86960 as follows:
+ * SRAM: 32KB, 100ns, byte-wide access.
+ * Transmission buffer: 4KB x 2.
+ * System bus interface: 16 bits.
+ */
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL;
+ sc->proto_dlcr5 = 0;
+ sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
+ | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_NICE;
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
+
+ /* Setup hooks. We need a special initialization procedure. */
+ sc->init = fe_init_mbh;
+
+ /*
+ * Minimum initialization.
+ */
+
+ /* Minimal initialization of 86960. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[ FE_DLCR2 ], 0 );
+ outb( sc->ioaddr[ FE_DLCR3 ], 0 );
+
+#if 1 /* FIXME. */
+ /* Initialize system bus interface and encoder/decoder operation. */
+ outb( sc->ioaddr[ FE_MBH0 ], FE_MBH0_MAGIC | FE_MBH0_INTR_DISABLE );
+#endif
+
+ /*
+ * That's all. MBH10302 occupies 32 I/O addresses, by the way.
+ */
+ return 32;
+}
+
+/* MBH specific initialization routine. */
+static void
+fe_init_mbh ( struct fe_softc * sc )
+{
+ /* Minimal initialization of 86960. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[ FE_DLCR2 ], 0 );
+ outb( sc->ioaddr[ FE_DLCR3 ], 0 );
+
+ /* Enable master interrupt flag. */
+ outb( sc->ioaddr[ FE_MBH0 ], FE_MBH0_MAGIC | FE_MBH0_INTR_ENABLE );
+}
+
+/*
+ * Probe and initialization for TDK/CONTEC PCMCIA Ethernet interface.
+ * by MASUI Kenji <masui@cs.titech.ac.jp>
+ *
+ * (Contec uses TDK Ethenet chip -- hosokawa)
+ *
+ * This version of fe_probe_tdk has been rewrote to handle
+ * *generic* PC card implementation of Fujitsu MB8696x and compatibles.
+ * The name _tdk is just for a historical reason. <seki> :-)
+ */
+static int
+fe_probe_tdk ( DEVICE * dev, struct fe_softc * sc )
+{
+ int i;
+
+ static struct fe_simple_probe_struct probe_table [] = {
+ { FE_DLCR2, 0x70, 0x00 },
+ { FE_DLCR4, 0x08, 0x00 },
+ /* { FE_DLCR5, 0x80, 0x00 }, Does not work well. */
+ { 0 }
+ };
+
+ /* We need an IRQ. */
+ if ( dev->id_irq == NO_IRQ ) {
+ return ( 0 );
+ }
+
+ /* Generic driver needs Ethernet address taken from CIS. */
+ if (sc->arpcom.ac_enaddr[0] == 0
+ && sc->arpcom.ac_enaddr[1] == 0
+ && sc->arpcom.ac_enaddr[2] == 0) {
+ return 0;
+ }
+
+ /* Setup an I/O address mapping table; we need only 16 ports. */
+ for (i = 0; i < 16; i++) {
+ sc->ioaddr[i] = sc->iobase + i;
+ }
+ /* Fill unused slots with a safe address. */
+ for (i = 16; i < MAXREGISTERS; i++) {
+ sc->ioaddr[i] = sc->iobase;
+ }
+
+ /*
+ * See if C-NET(PC)C is on its address.
+ */
+
+ if ( !fe_simple_probe( sc, probe_table ) ) return 0;
+
+ /* Determine the card type. */
+ sc->typestr = "Generic MB8696x Ethernet (PCMCIA)";
+
+ /*
+ * Initialize constants in the per-line structure.
+ */
+
+ /* The station address *must*be* already in sc_enaddr;
+ Make sure we got a valid station address. */
+ if ( ( sc->sc_enaddr[ 0 ] & 0x03 ) != 0x00
+ || ( sc->sc_enaddr[ 0 ] == 0x00
+ && sc->sc_enaddr[ 1 ] == 0x00
+ && sc->sc_enaddr[ 2 ] == 0x00 ) ) return 0;
+
+ /*
+ * Program the 86965 as follows:
+ * SRAM: 32KB, 100ns, byte-wide access.
+ * Transmission buffer: 4KB x 2.
+ * System bus interface: 16 bits.
+ * XXX: Should we remove IDENT_NICE from DLCR7? Or,
+ * even add IDENT_EC instead? FIXME.
+ */
+ sc->proto_dlcr4 = FE_D4_LBC_DISABLE | FE_D4_CNTRL;
+ sc->proto_dlcr5 = 0;
+ sc->proto_dlcr6 = FE_D6_BUFSIZ_32KB | FE_D6_TXBSIZ_2x4KB
+ | FE_D6_BBW_BYTE | FE_D6_SBW_WORD | FE_D6_SRAM_100ns;
+ sc->proto_dlcr7 = FE_D7_BYTSWP_LH | FE_D7_IDENT_NICE;
+ sc->proto_bmpr13 = FE_B13_TPTYPE_UTP | FE_B13_PORT_AUTO;
+
+ /* Minimul initialization of 86960. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Disable all interrupts. */
+ outb( sc->ioaddr[ FE_DLCR2 ], 0 );
+ outb( sc->ioaddr[ FE_DLCR3 ], 0 );
+
+ /*
+ * That's all. C-NET(PC)C occupies 16 I/O addresses.
+ *
+ * Some PC cards (e.g., TDK and Contec) have 16 I/O addresses,
+ * while some others (e.g., Fujitsu) have 32. Fortunately,
+ * this generic driver never accesses latter 16 ports in 32
+ * ports cards. So, we can assume the *generic* PC cards
+ * always have 16 ports.
+ *
+ * Moreover, PC card probe is isolated from ISA probe, and PC
+ * card probe routine doesn't use "# of ports" returned by this
+ * function. 16 v.s. 32 is not important now.
+ */
+ return 16;
+}
+#endif /* NCARD > 0 */
+
+/*
+ * Install interface into kernel networking data structures
+ */
+static int
+fe_attach ( DEVICE * dev )
+{
+#if NCARD > 0
+ static int already_ifattach[NFE];
+#endif
+ struct fe_softc *sc = &fe_softc[dev->id_unit];
+
+ /*
+ * Initialize ifnet structure
+ */
+ sc->sc_if.if_softc = sc;
+ sc->sc_if.if_unit = sc->sc_unit;
+ sc->sc_if.if_name = "fe";
+ sc->sc_if.if_output = ether_output;
+ sc->sc_if.if_start = fe_start;
+ sc->sc_if.if_ioctl = fe_ioctl;
+ sc->sc_if.if_watchdog = fe_watchdog;
+
+ /*
+ * Set default interface flags.
+ */
+ sc->sc_if.if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+
+ /*
+ * Set maximum size of output queue, if it has not been set.
+ * It is done here as this driver may be started after the
+ * system initialization (i.e., the interface is PCMCIA.)
+ *
+ * I'm not sure this is really necessary, but, even if it is,
+ * it should be done somewhere else, e.g., in if_attach(),
+ * since it must be a common workaround for all network drivers.
+ * FIXME.
+ */
+ if ( sc->sc_if.if_snd.ifq_maxlen == 0 ) {
+ sc->sc_if.if_snd.ifq_maxlen = ifqmaxlen;
+ }
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "attach()" );
+#endif
+
+#if FE_SINGLE_TRANSMISSION
+ /* Override txb config to allocate minimum. */
+ sc->proto_dlcr6 &= ~FE_D6_TXBSIZ
+ sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB;
+#endif
+
+ /* Modify hardware config if it is requested. */
+ if ( dev->id_flags & FE_FLAGS_OVERRIDE_DLCR6 ) {
+ sc->proto_dlcr6 = dev->id_flags & FE_FLAGS_DLCR6_VALUE;
+ }
+
+ /* Find TX buffer size, based on the hardware dependent proto. */
+ switch ( sc->proto_dlcr6 & FE_D6_TXBSIZ ) {
+ case FE_D6_TXBSIZ_2x2KB: sc->txb_size = 2048; break;
+ case FE_D6_TXBSIZ_2x4KB: sc->txb_size = 4096; break;
+ case FE_D6_TXBSIZ_2x8KB: sc->txb_size = 8192; break;
+ default:
+ /* Oops, we can't work with single buffer configuration. */
+#if FE_DEBUG >= 2
+ log( LOG_WARNING, "fe%d: strange TXBSIZ config; fixing\n",
+ sc->sc_unit );
+#endif
+ sc->proto_dlcr6 &= ~FE_D6_TXBSIZ;
+ sc->proto_dlcr6 |= FE_D6_TXBSIZ_2x2KB;
+ sc->txb_size = 2048;
+ break;
+ }
+
+ /* Attach and stop the interface. */
+#if NCARD > 0
+ if (already_ifattach[dev->id_unit] != 1) {
+ if_attach(&sc->sc_if);
+ already_ifattach[dev->id_unit] = 1;
+ }
+#else
+ if_attach(&sc->sc_if);
+#endif
+ fe_stop(sc->sc_unit); /* This changes the state to IDLE. */
+ ether_ifattach(&sc->sc_if);
+
+ /* Print additional info when attached. */
+ printf( "fe%d: address %6D, type %s\n", sc->sc_unit,
+ sc->sc_enaddr, ":" , sc->typestr );
+#if FE_DEBUG >= 3
+ {
+ int buf, txb, bbw, sbw, ram;
+
+ buf = txb = bbw = sbw = ram = -1;
+ switch ( sc->proto_dlcr6 & FE_D6_BUFSIZ ) {
+ case FE_D6_BUFSIZ_8KB: buf = 8; break;
+ case FE_D6_BUFSIZ_16KB: buf = 16; break;
+ case FE_D6_BUFSIZ_32KB: buf = 32; break;
+ case FE_D6_BUFSIZ_64KB: buf = 64; break;
+ }
+ switch ( sc->proto_dlcr6 & FE_D6_TXBSIZ ) {
+ case FE_D6_TXBSIZ_2x2KB: txb = 2; break;
+ case FE_D6_TXBSIZ_2x4KB: txb = 4; break;
+ case FE_D6_TXBSIZ_2x8KB: txb = 8; break;
+ }
+ switch ( sc->proto_dlcr6 & FE_D6_BBW ) {
+ case FE_D6_BBW_BYTE: bbw = 8; break;
+ case FE_D6_BBW_WORD: bbw = 16; break;
+ }
+ switch ( sc->proto_dlcr6 & FE_D6_SBW ) {
+ case FE_D6_SBW_BYTE: sbw = 8; break;
+ case FE_D6_SBW_WORD: sbw = 16; break;
+ }
+ switch ( sc->proto_dlcr6 & FE_D6_SRAM ) {
+ case FE_D6_SRAM_100ns: ram = 100; break;
+ case FE_D6_SRAM_150ns: ram = 150; break;
+ }
+ printf( "fe%d: SRAM %dKB %dbit %dns, TXB %dKBx2, %dbit I/O\n",
+ sc->sc_unit, buf, bbw, ram, txb, sbw );
+ }
+#endif
+
+#if NBPFILTER > 0
+ /* If BPF is in the kernel, call the attach for it. */
+ bpfattach( &sc->sc_if, DLT_EN10MB, sizeof(struct ether_header));
+#endif
+ return 1;
+}
+
+/*
+ * Reset interface.
+ */
+static void
+fe_reset ( int unit )
+{
+ /*
+ * Stop interface and re-initialize.
+ */
+ fe_stop(unit);
+ fe_init(unit);
+}
+
+/*
+ * Stop everything on the interface.
+ *
+ * All buffered packets, both transmitting and receiving,
+ * if any, will be lost by stopping the interface.
+ */
+static void
+fe_stop ( int unit )
+{
+ struct fe_softc *sc = &fe_softc[unit];
+ int s;
+
+ s = splimp();
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "stop()" );
+#endif
+
+ /* Disable interrupts. */
+ outb( sc->ioaddr[ FE_DLCR2 ], 0x00 );
+ outb( sc->ioaddr[ FE_DLCR3 ], 0x00 );
+
+ /* Stop interface hardware. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Clear all interrupt status. */
+ outb( sc->ioaddr[ FE_DLCR0 ], 0xFF );
+ outb( sc->ioaddr[ FE_DLCR1 ], 0xFF );
+
+ /* Put the chip in stand-by mode. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR7 ], sc->proto_dlcr7 | FE_D7_POWER_DOWN );
+ DELAY( 200 );
+
+ /* Reset transmitter variables and interface flags. */
+ sc->sc_if.if_flags &= ~( IFF_OACTIVE | IFF_RUNNING );
+ sc->sc_if.if_timer = 0;
+ sc->txb_free = sc->txb_size;
+ sc->txb_count = 0;
+ sc->txb_sched = 0;
+
+ /* MAR loading can be delayed. */
+ sc->filter_change = 0;
+
+ /* Update config status also. */
+
+ /* Call a hook. */
+ if ( sc->stop ) sc->stop( sc );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "end of stop()" );
+#endif
+
+ (void) splx(s);
+}
+
+/*
+ * Device timeout/watchdog routine. Entered if the device neglects to
+ * generate an interrupt after a transmit has been started on it.
+ */
+static void
+fe_watchdog ( struct ifnet *ifp )
+{
+ struct fe_softc *sc = (struct fe_softc *)ifp;
+
+#if FE_DEBUG >= 1
+ /* A "debug" message. */
+ log( LOG_ERR, "fe%d: transmission timeout (%d+%d)%s\n",
+ ifp->if_unit, sc->txb_sched, sc->txb_count,
+ ( ifp->if_flags & IFF_UP ) ? "" : " when down" );
+ if ( sc->sc_if.if_opackets == 0 && sc->sc_if.if_ipackets == 0 ) {
+ log( LOG_WARNING, "fe%d: wrong IRQ setting in config?\n",
+ ifp->if_unit );
+ }
+#endif
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, NULL );
+#endif
+
+ /* Record how many packets are lost by this accident. */
+ ifp->if_oerrors += sc->txb_sched + sc->txb_count;
+
+ /* Put the interface into known initial state. */
+ if ( ifp->if_flags & IFF_UP ) {
+ fe_reset( ifp->if_unit );
+ } else {
+ fe_stop( ifp->if_unit );
+ }
+}
+
+/*
+ * Initialize device.
+ */
+static void
+fe_init ( int unit )
+{
+ struct fe_softc *sc = &fe_softc[unit];
+ int s;
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "init()" );
+#endif
+
+ /* We need an address. */
+ if (TAILQ_EMPTY(&sc->sc_if.if_addrhead)) { /* XXX unlikely */
+#if FE_DEBUG >= 1
+ log( LOG_ERR, "fe%d: init() without any address\n",
+ sc->sc_unit );
+#endif
+ return;
+ }
+
+#if FE_DEBUG >= 1
+ /*
+ * Make sure we have a valid station address.
+ * The following test is applicable for any Ethernet interfaces.
+ * It can be done in somewhere common to all of them. FIXME.
+ */
+ if ( ( sc->sc_enaddr[ 0 ] & 0x01 ) != 0
+ || ( sc->sc_enaddr[ 0 ] == 0x00
+ && sc->sc_enaddr[ 1 ] == 0x00
+ && sc->sc_enaddr[ 2 ] == 0x00 ) ) {
+ log( LOG_ERR, "fe%d: invalid station address (%6D)\n",
+ sc->sc_unit, sc->sc_enaddr, ":" );
+ return;
+ }
+#endif
+
+ /* Start initializing 86960. */
+ s = splimp();
+
+ /* Call a hook. */
+ if ( sc->init ) sc->init( sc );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "after init hook" );
+#endif
+
+ /*
+ * Make sure to disable the chip, also.
+ * This may also help re-programming the chip after
+ * hot insertion of PCMCIAs.
+ */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Power up the chip and select register bank for DLCRs. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR7 ],
+ sc->proto_dlcr7 | FE_D7_RBS_DLCR | FE_D7_POWER_UP );
+ DELAY( 200 );
+
+ /* Feed the station address. */
+ outblk( sc, FE_DLCR8, sc->sc_enaddr, ETHER_ADDR_LEN );
+
+ /* Clear multicast address filter to receive nothing. */
+ outb( sc->ioaddr[ FE_DLCR7 ],
+ sc->proto_dlcr7 | FE_D7_RBS_MAR | FE_D7_POWER_UP );
+ outblk( sc, FE_MAR8, fe_filter_nothing.data, FE_FILTER_LEN );
+
+ /* Select the BMPR bank for runtime register access. */
+ outb( sc->ioaddr[ FE_DLCR7 ],
+ sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP );
+
+ /* Initialize registers. */
+ outb( sc->ioaddr[ FE_DLCR0 ], 0xFF ); /* Clear all bits. */
+ outb( sc->ioaddr[ FE_DLCR1 ], 0xFF ); /* ditto. */
+ outb( sc->ioaddr[ FE_DLCR2 ], 0x00 );
+ outb( sc->ioaddr[ FE_DLCR3 ], 0x00 );
+ outb( sc->ioaddr[ FE_DLCR4 ], sc->proto_dlcr4 );
+ outb( sc->ioaddr[ FE_DLCR5 ], sc->proto_dlcr5 );
+ outb( sc->ioaddr[ FE_BMPR10 ], 0x00 );
+ outb( sc->ioaddr[ FE_BMPR11 ], FE_B11_CTRL_SKIP | FE_B11_MODE1 );
+ outb( sc->ioaddr[ FE_BMPR12 ], 0x00 );
+ outb( sc->ioaddr[ FE_BMPR13 ], sc->proto_bmpr13 );
+ outb( sc->ioaddr[ FE_BMPR14 ], 0x00 );
+ outb( sc->ioaddr[ FE_BMPR15 ], 0x00 );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "just before enabling DLC" );
+#endif
+
+ /* Enable interrupts. */
+ outb( sc->ioaddr[ FE_DLCR2 ], FE_TMASK );
+ outb( sc->ioaddr[ FE_DLCR3 ], FE_RMASK );
+
+ /* Enable transmitter and receiver. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_ENABLE );
+ DELAY( 200 );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "just after enabling DLC" );
+#endif
+
+ /*
+ * Make sure to empty the receive buffer.
+ *
+ * This may be redundant, but *if* the receive buffer were full
+ * at this point, then the driver would hang. I have experienced
+ * some strange hang-up just after UP. I hope the following
+ * code solve the problem.
+ *
+ * I have changed the order of hardware initialization.
+ * I think the receive buffer cannot have any packets at this
+ * point in this version. The following code *must* be
+ * redundant now. FIXME.
+ *
+ * I've heard a rumore that on some PC card implementation of
+ * 8696x, the receive buffer can have some data at this point.
+ * The following message helps discovering the fact. FIXME.
+ */
+ if ( !( inb( sc->ioaddr[ FE_DLCR5 ] ) & FE_D5_BUFEMP ) ) {
+ log( LOG_WARNING,
+ "fe%d: receive buffer has some data after reset\n",
+ sc->sc_unit );
+
+ fe_emptybuffer( sc );
+ }
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "after ERB loop" );
+#endif
+
+ /* Do we need this here? Actually, no. I must be paranoia. */
+ outb( sc->ioaddr[ FE_DLCR0 ], 0xFF ); /* Clear all bits. */
+ outb( sc->ioaddr[ FE_DLCR1 ], 0xFF ); /* ditto. */
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "after FIXME" );
+#endif
+ /* Set 'running' flag, because we are now running. */
+ sc->sc_if.if_flags |= IFF_RUNNING;
+
+ /*
+ * At this point, the interface is running properly,
+ * except that it receives *no* packets. we then call
+ * fe_setmode() to tell the chip what packets to be
+ * received, based on the if_flags and multicast group
+ * list. It completes the initialization process.
+ */
+ fe_setmode( sc );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "after setmode" );
+#endif
+
+ /* ...and attempt to start output queued packets. */
+ fe_start( &sc->sc_if );
+
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, "init() done" );
+#endif
+
+ (void) splx(s);
+}
+
+/*
+ * This routine actually starts the transmission on the interface
+ */
+static void
+fe_xmit ( struct fe_softc * sc )
+{
+ /*
+ * Set a timer just in case we never hear from the board again.
+ * We use longer timeout for multiple packet transmission.
+ * I'm not sure this timer value is appropriate. FIXME.
+ */
+ sc->sc_if.if_timer = 1 + sc->txb_count;
+
+ /* Update txb variables. */
+ sc->txb_sched = sc->txb_count;
+ sc->txb_count = 0;
+ sc->txb_free = sc->txb_size;
+ sc->tx_excolls = 0;
+
+ /* Start transmitter, passing packets in TX buffer. */
+ outb( sc->ioaddr[ FE_BMPR10 ], sc->txb_sched | FE_B10_START );
+}
+
+/*
+ * Start output on interface.
+ * We make two assumptions here:
+ * 1) that the current priority is set to splimp _before_ this code
+ * is called *and* is returned to the appropriate priority after
+ * return
+ * 2) that the IFF_OACTIVE flag is checked before this code is called
+ * (i.e. that the output part of the interface is idle)
+ */
+void
+fe_start ( struct ifnet *ifp )
+{
+ struct fe_softc *sc = ifp->if_softc;
+ struct mbuf *m;
+
+#if FE_DEBUG >= 1
+ /* Just a sanity check. */
+ if ( ( sc->txb_count == 0 ) != ( sc->txb_free == sc->txb_size ) ) {
+ /*
+ * Txb_count and txb_free co-works to manage the
+ * transmission buffer. Txb_count keeps track of the
+ * used potion of the buffer, while txb_free does unused
+ * potion. So, as long as the driver runs properly,
+ * txb_count is zero if and only if txb_free is same
+ * as txb_size (which represents whole buffer.)
+ */
+ log( LOG_ERR, "fe%d: inconsistent txb variables (%d, %d)\n",
+ sc->sc_unit, sc->txb_count, sc->txb_free );
+ /*
+ * So, what should I do, then?
+ *
+ * We now know txb_count and txb_free contradicts. We
+ * cannot, however, tell which is wrong. More
+ * over, we cannot peek 86960 transmission buffer or
+ * reset the transmission buffer. (In fact, we can
+ * reset the entire interface. I don't want to do it.)
+ *
+ * If txb_count is incorrect, leaving it as-is will cause
+ * sending of garbage after next interrupt. We have to
+ * avoid it. Hence, we reset the txb_count here. If
+ * txb_free was incorrect, resetting txb_count just loose
+ * some packets. We can live with it.
+ */
+ sc->txb_count = 0;
+ }
+#endif
+
+#if FE_DEBUG >= 1
+ /*
+ * First, see if there are buffered packets and an idle
+ * transmitter - should never happen at this point.
+ */
+ if ( ( sc->txb_count > 0 ) && ( sc->txb_sched == 0 ) ) {
+ log( LOG_ERR,
+ "fe%d: transmitter idle with %d buffered packets\n",
+ sc->sc_unit, sc->txb_count );
+ fe_xmit( sc );
+ }
+#endif
+
+ /*
+ * Stop accepting more transmission packets temporarily, when
+ * a filter change request is delayed. Updating the MARs on
+ * 86960 flushes the transmission buffer, so it is delayed
+ * until all buffered transmission packets have been sent
+ * out.
+ */
+ if ( sc->filter_change ) {
+ /*
+ * Filter change request is delayed only when the DLC is
+ * working. DLC soon raise an interrupt after finishing
+ * the work.
+ */
+ goto indicate_active;
+ }
+
+ for (;;) {
+
+ /*
+ * See if there is room to put another packet in the buffer.
+ * We *could* do better job by peeking the send queue to
+ * know the length of the next packet. Current version just
+ * tests against the worst case (i.e., longest packet). FIXME.
+ *
+ * When adding the packet-peek feature, don't forget adding a
+ * test on txb_count against QUEUEING_MAX.
+ * There is a little chance the packet count exceeds
+ * the limit. Assume transmission buffer is 8KB (2x8KB
+ * configuration) and an application sends a bunch of small
+ * (i.e., minimum packet sized) packets rapidly. An 8KB
+ * buffer can hold 130 blocks of 62 bytes long...
+ */
+ if ( sc->txb_free
+ < ETHER_MAX_LEN - ETHER_CRC_LEN + FE_DATA_LEN_LEN ) {
+ /* No room. */
+ goto indicate_active;
+ }
+
+#if FE_SINGLE_TRANSMISSION
+ if ( sc->txb_count > 0 ) {
+ /* Just one packet per a transmission buffer. */
+ goto indicate_active;
+ }
+#endif
+
+ /*
+ * Get the next mbuf chain for a packet to send.
+ */
+ IF_DEQUEUE( &sc->sc_if.if_snd, m );
+ if ( m == NULL ) {
+ /* No more packets to send. */
+ goto indicate_inactive;
+ }
+
+ /*
+ * Copy the mbuf chain into the transmission buffer.
+ * txb_* variables are updated as necessary.
+ */
+ fe_write_mbufs( sc, m );
+
+ /* Start transmitter if it's idle. */
+ if ( ( sc->txb_count > 0 ) && ( sc->txb_sched == 0 ) ) {
+ fe_xmit( sc );
+ }
+
+ /*
+ * Tap off here if there is a bpf listener,
+ * and the device is *not* in promiscuous mode.
+ * (86960 receives self-generated packets if
+ * and only if it is in "receive everything"
+ * mode.)
+ */
+#if NBPFILTER > 0
+ if ( sc->sc_if.if_bpf
+ && !( sc->sc_if.if_flags & IFF_PROMISC ) ) {
+ bpf_mtap( &sc->sc_if, m );
+ }
+#endif
+
+ m_freem( m );
+ }
+
+ indicate_inactive:
+ /*
+ * We are using the !OACTIVE flag to indicate to
+ * the outside world that we can accept an
+ * additional packet rather than that the
+ * transmitter is _actually_ active. Indeed, the
+ * transmitter may be active, but if we haven't
+ * filled all the buffers with data then we still
+ * want to accept more.
+ */
+ sc->sc_if.if_flags &= ~IFF_OACTIVE;
+ return;
+
+ indicate_active:
+ /*
+ * The transmitter is active, and there are no room for
+ * more outgoing packets in the transmission buffer.
+ */
+ sc->sc_if.if_flags |= IFF_OACTIVE;
+ return;
+}
+
+/*
+ * Drop (skip) a packet from receive buffer in 86960 memory.
+ */
+static void
+fe_droppacket ( struct fe_softc * sc, int len )
+{
+ int i;
+
+ /*
+ * 86960 manual says that we have to read 8 bytes from the buffer
+ * before skip the packets and that there must be more than 8 bytes
+ * remaining in the buffer when issue a skip command.
+ * Remember, we have already read 4 bytes before come here.
+ */
+ if ( len > 12 ) {
+ /* Read 4 more bytes, and skip the rest of the packet. */
+ ( void )inw( sc->ioaddr[ FE_BMPR8 ] );
+ ( void )inw( sc->ioaddr[ FE_BMPR8 ] );
+ outb( sc->ioaddr[ FE_BMPR14 ], sc->proto_bmpr14 | FE_B14_SKIP );
+ } else {
+ /* We should not come here unless receiving RUNTs. */
+ for ( i = 0; i < len; i += 2 ) {
+ ( void )inw( sc->ioaddr[ FE_BMPR8 ] );
+ }
+ }
+}
+
+/*
+ * Empty receiving buffer.
+ */
+static void
+fe_emptybuffer ( struct fe_softc * sc )
+{
+ int i;
+ u_char saved_dlcr5;
+
+#if FE_DEBUG >= 2
+ log( LOG_WARNING, "fe%d: emptying receive buffer\n", sc->sc_unit );
+#endif
+ /*
+ * Stop receiving packets, temporarily.
+ */
+ saved_dlcr5 = inb( sc->ioaddr[ FE_DLCR5 ] );
+ outb( sc->ioaddr[ FE_DLCR5 ], sc->proto_dlcr5 );
+ DELAY(1300);
+
+ /*
+ * When we come here, the receive buffer management should
+ * have been broken. So, we cannot use skip operation.
+ * Just discard everything in the buffer.
+ */
+ for (i = 0; i < 32768; i++) {
+ if ( inb( sc->ioaddr[ FE_DLCR5 ] ) & FE_D5_BUFEMP ) break;
+ ( void )inw( sc->ioaddr[ FE_BMPR8 ] );
+ }
+
+ /*
+ * Double check.
+ */
+ if ( inb( sc->ioaddr[ FE_DLCR5 ] ) & FE_D5_BUFEMP ) {
+ log( LOG_ERR, "fe%d: could not empty receive buffer\n",
+ sc->sc_unit );
+ /* Hmm. What should I do if this happens? FIXME. */
+ }
+
+ /*
+ * Restart receiving packets.
+ */
+ outb( sc->ioaddr[ FE_DLCR5 ], saved_dlcr5 );
+}
+
+/*
+ * Transmission interrupt handler
+ * The control flow of this function looks silly. FIXME.
+ */
+static void
+fe_tint ( struct fe_softc * sc, u_char tstat )
+{
+ int left;
+ int col;
+
+ /*
+ * Handle "excessive collision" interrupt.
+ */
+ if ( tstat & FE_D0_COLL16 ) {
+
+ /*
+ * Find how many packets (including this collided one)
+ * are left unsent in transmission buffer.
+ */
+ left = inb( sc->ioaddr[ FE_BMPR10 ] );
+
+#if FE_DEBUG >= 2
+ log( LOG_WARNING, "fe%d: excessive collision (%d/%d)\n",
+ sc->sc_unit, left, sc->txb_sched );
+#endif
+#if FE_DEBUG >= 3
+ fe_dump( LOG_INFO, sc, NULL );
+#endif
+
+ /*
+ * Clear the collision flag (in 86960) here
+ * to avoid confusing statistics.
+ */
+ outb( sc->ioaddr[ FE_DLCR0 ], FE_D0_COLLID );
+
+ /*
+ * Restart transmitter, skipping the
+ * collided packet.
+ *
+ * We *must* skip the packet to keep network running
+ * properly. Excessive collision error is an
+ * indication of the network overload. If we
+ * tried sending the same packet after excessive
+ * collision, the network would be filled with
+ * out-of-time packets. Packets belonging
+ * to reliable transport (such as TCP) are resent
+ * by some upper layer.
+ */
+ outb( sc->ioaddr[ FE_BMPR11 ],
+ FE_B11_CTRL_SKIP | FE_B11_MODE1 );
+
+ /* Update statistics. */
+ sc->tx_excolls++;
+ }
+
+ /*
+ * Handle "transmission complete" interrupt.
+ */
+ if ( tstat & FE_D0_TXDONE ) {
+
+ /*
+ * Add in total number of collisions on last
+ * transmission. We also clear "collision occurred" flag
+ * here.
+ *
+ * 86960 has a design flaw on collision count on multiple
+ * packet transmission. When we send two or more packets
+ * with one start command (that's what we do when the
+ * transmission queue is crowded), 86960 informs us number
+ * of collisions occurred on the last packet on the
+ * transmission only. Number of collisions on previous
+ * packets are lost. I have told that the fact is clearly
+ * stated in the Fujitsu document.
+ *
+ * I considered not to mind it seriously. Collision
+ * count is not so important, anyway. Any comments? FIXME.
+ */
+
+ if ( inb( sc->ioaddr[ FE_DLCR0 ] ) & FE_D0_COLLID ) {
+
+ /* Clear collision flag. */
+ outb( sc->ioaddr[ FE_DLCR0 ], FE_D0_COLLID );
+
+ /* Extract collision count from 86960. */
+ col = inb( sc->ioaddr[ FE_DLCR4 ] );
+ col = ( col & FE_D4_COL ) >> FE_D4_COL_SHIFT;
+ if ( col == 0 ) {
+ /*
+ * Status register indicates collisions,
+ * while the collision count is zero.
+ * This can happen after multiple packet
+ * transmission, indicating that one or more
+ * previous packet(s) had been collided.
+ *
+ * Since the accurate number of collisions
+ * has been lost, we just guess it as 1;
+ * Am I too optimistic? FIXME.
+ */
+ col = 1;
+ }
+ sc->sc_if.if_collisions += col;
+#if FE_DEBUG >= 3
+ log( LOG_WARNING, "fe%d: %d collision(s) (%d)\n",
+ sc->sc_unit, col, sc->txb_sched );
+#endif
+ }
+
+ /*
+ * Update transmission statistics.
+ * Be sure to reflect number of excessive collisions.
+ */
+ sc->sc_if.if_opackets += sc->txb_sched - sc->tx_excolls;
+ sc->sc_if.if_oerrors += sc->tx_excolls;
+ sc->sc_if.if_collisions += sc->tx_excolls * 16;
+ sc->txb_sched = 0;
+
+ /*
+ * The transmitter is no more active.
+ * Reset output active flag and watchdog timer.
+ */
+ sc->sc_if.if_flags &= ~IFF_OACTIVE;
+ sc->sc_if.if_timer = 0;
+
+ /*
+ * If more data is ready to transmit in the buffer, start
+ * transmitting them. Otherwise keep transmitter idle,
+ * even if more data is queued. This gives receive
+ * process a slight priority.
+ */
+ if ( sc->txb_count > 0 ) fe_xmit( sc );
+ }
+}
+
+/*
+ * Ethernet interface receiver interrupt.
+ */
+static void
+fe_rint ( struct fe_softc * sc, u_char rstat )
+{
+ u_short len;
+ u_char status;
+ int i;
+
+ /*
+ * Update statistics if this interrupt is caused by an error.
+ */
+ if ( rstat & ( FE_D1_OVRFLO | FE_D1_CRCERR
+ | FE_D1_ALGERR | FE_D1_SRTPKT ) ) {
+#if FE_DEBUG >= 2
+ log( LOG_WARNING,
+ "fe%d: receive error: %s%s%s%s(%02x)\n",
+ sc->sc_unit,
+ rstat & FE_D1_OVRFLO ? "OVR " : "",
+ rstat & FE_D1_CRCERR ? "CRC " : "",
+ rstat & FE_D1_ALGERR ? "ALG " : "",
+ rstat & FE_D1_SRTPKT ? "LEN " : "",
+ rstat );
+#endif
+ sc->sc_if.if_ierrors++;
+ }
+
+ /*
+ * MB86960 has a flag indicating "receive queue empty."
+ * We just loop, checking the flag, to pull out all received
+ * packets.
+ *
+ * We limit the number of iterations to avoid infinite-loop.
+ * The upper bound is set to unrealistic high value.
+ */
+ for (i = 0; i < FE_MAX_RECV_COUNT * 2; i++) {
+
+ /* Stop the iteration if 86960 indicates no packets. */
+ if ( inb( sc->ioaddr[ FE_DLCR5 ] ) & FE_D5_BUFEMP ) break;
+
+ /*
+ * Extract A receive status byte.
+ * As our 86960 is in 16 bit bus access mode, we have to
+ * use inw() to get the status byte. The significant
+ * value is returned in lower 8 bits.
+ */
+ status = ( u_char )inw( sc->ioaddr[ FE_BMPR8 ] );
+#if FE_DEBUG >= 4
+ log( LOG_INFO, "fe%d: receive status = %04x\n",
+ sc->sc_unit, status );
+#endif
+
+ /*
+ * Extract the packet length.
+ * It is a sum of a header (14 bytes) and a payload.
+ * CRC has been stripped off by the 86960.
+ */
+ len = inw( sc->ioaddr[ FE_BMPR8 ] );
+
+#if FE_DEBUG >= 1
+ /*
+ * If there was an error with the received packet, it
+ * must be an indication of out-of-sync on receive
+ * buffer, because we have programmed the 8696x to
+ * to discard errored packets, even when the interface
+ * is in promiscuous mode. We have to re-synchronize.
+ */
+ if (!(status & FE_RPH_GOOD)) {
+ log(LOG_ERR,
+ "fe%d: corrupted receive status byte (%02x)\n",
+ sc->arpcom.ac_if.if_unit, status);
+ sc->arpcom.ac_if.if_ierrors++;
+ fe_emptybuffer( sc );
+ break;
+ }
+#endif
+
+#if FE_DEBUG >= 1
+ /*
+ * MB86960 checks the packet length and drop big packet
+ * before passing it to us. There are no chance we can
+ * get big packets through it, even if they are actually
+ * sent over a line. Hence, if the length exceeds
+ * the specified limit, it means some serious failure,
+ * such as out-of-sync on receive buffer management.
+ *
+ * Same for short packets, since we have programmed
+ * 86960 to drop short packets.
+ */
+ if ( len > ETHER_MAX_LEN - ETHER_CRC_LEN
+ || len < ETHER_MIN_LEN - ETHER_CRC_LEN ) {
+ log( LOG_WARNING,
+ "fe%d: received a %s packet? (%u bytes)\n",
+ sc->sc_unit,
+ len < ETHER_MIN_LEN - ETHER_CRC_LEN
+ ? "partial" : "big",
+ len );
+ sc->sc_if.if_ierrors++;
+ fe_emptybuffer( sc );
+ break;
+ }
+#endif
+
+ /*
+ * Go get a packet.
+ */
+ if ( fe_get_packet( sc, len ) < 0 ) {
+
+#if FE_DEBUG >= 2
+ log( LOG_WARNING, "%s%d: out of mbuf;"
+ " dropping a packet (%u bytes)\n",
+ sc->sc_unit, len );
+#endif
+
+ /* Skip a packet, updating statistics. */
+ sc->sc_if.if_ierrors++;
+ fe_droppacket( sc, len );
+
+ /*
+ * Try extracting other packets, although they will
+ * cause out-of-mbuf error again. This is required
+ * to keep receiver interrupt comming.
+ * (Earlier versions had a bug on this point.)
+ */
+ continue;
+ }
+
+ /* Successfully received a packet. Update stat. */
+ sc->sc_if.if_ipackets++;
+ }
+}
+
+/*
+ * Ethernet interface interrupt processor
+ */
+void
+feintr ( int unit )
+{
+ struct fe_softc *sc = &fe_softc[unit];
+ u_char tstat, rstat;
+
+ /*
+ * Loop until there are no more new interrupt conditions.
+ */
+ for (;;) {
+
+#if FE_DEBUG >= 4
+ fe_dump( LOG_INFO, sc, "intr()" );
+#endif
+
+ /*
+ * Get interrupt conditions, masking unneeded flags.
+ */
+ tstat = inb( sc->ioaddr[ FE_DLCR0 ] ) & FE_TMASK;
+ rstat = inb( sc->ioaddr[ FE_DLCR1 ] ) & FE_RMASK;
+
+#if FE_DEBUG >= 1
+ /* Test for a "dead-lock" condition. */
+ if ((rstat & FE_D1_PKTRDY) == 0
+ && (inb(sc->ioaddr[FE_DLCR5]) & FE_D5_BUFEMP) == 0
+ && (inb(sc->ioaddr[FE_DLCR1]) & FE_D1_PKTRDY) == 0) {
+ /*
+ * PKTRDY is off, while receive buffer is not empty.
+ * We did a double check to avoid a race condition...
+ * So, we should have missed an interrupt.
+ */
+ log(LOG_WARNING,
+ "fe%d: missed a receiver interrupt?\n",
+ sc->arpcom.ac_if.if_unit);
+ /* Simulate the missed interrupt condition. */
+ rstat |= FE_D1_PKTRDY;
+ }
+#endif
+
+ /* Stop processing if there are no interrupts to handle. */
+ if ( tstat == 0 && rstat == 0 ) break;
+
+ /*
+ * Reset the conditions we are acknowledging.
+ */
+ outb( sc->ioaddr[ FE_DLCR0 ], tstat );
+ outb( sc->ioaddr[ FE_DLCR1 ], rstat );
+
+ /*
+ * Handle transmitter interrupts. Handle these first because
+ * the receiver will reset the board under some conditions.
+ */
+ if ( tstat ) {
+ fe_tint( sc, tstat );
+ }
+
+ /*
+ * Handle receiver interrupts
+ */
+ if ( rstat ) {
+ fe_rint( sc, rstat );
+ }
+
+ /*
+ * Update the multicast address filter if it is
+ * needed and possible. We do it now, because
+ * we can make sure the transmission buffer is empty,
+ * and there is a good chance that the receive queue
+ * is empty. It will minimize the possibility of
+ * packet loss.
+ */
+ if ( sc->filter_change
+ && sc->txb_count == 0 && sc->txb_sched == 0 ) {
+ fe_loadmar(sc);
+ sc->sc_if.if_flags &= ~IFF_OACTIVE;
+ }
+
+ /*
+ * If it looks like the transmitter can take more data,
+ * attempt to start output on the interface. This is done
+ * after handling the receiver interrupt to give the
+ * receive operation priority.
+ *
+ * BTW, I'm not sure in what case the OACTIVE is on at
+ * this point. Is the following test redundant?
+ *
+ * No. This routine polls for both transmitter and
+ * receiver interrupts. 86960 can raise a receiver
+ * interrupt when the transmission buffer is full.
+ */
+ if ( ( sc->sc_if.if_flags & IFF_OACTIVE ) == 0 ) {
+ fe_start( &sc->sc_if );
+ }
+
+ }
+}
+
+/*
+ * Process an ioctl request. This code needs some work - it looks
+ * pretty ugly.
+ */
+static int
+fe_ioctl ( struct ifnet * ifp, u_long command, caddr_t data )
+{
+ struct fe_softc *sc = ifp->if_softc;
+ int s, error = 0;
+
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: ioctl(%x)\n", sc->sc_unit, command );
+#endif
+
+ s = splimp();
+
+ switch (command) {
+
+ case SIOCSIFADDR:
+ {
+ struct ifaddr * ifa = ( struct ifaddr * )data;
+
+ sc->sc_if.if_flags |= IFF_UP;
+
+ switch (ifa->ifa_addr->sa_family) {
+#ifdef INET
+ case AF_INET:
+ fe_init( sc->sc_unit ); /* before arp_ifinit */
+ arp_ifinit( &sc->arpcom, ifa );
+ break;
+#endif
+#ifdef IPX
+ /*
+ * XXX - This code is probably wrong
+ */
+ case AF_IPX:
+ {
+ register struct ipx_addr *ina
+ = &(IA_SIPX(ifa)->sipx_addr);
+
+ if (ipx_nullhost(*ina))
+ ina->x_host =
+ *(union ipx_host *) (sc->sc_enaddr); else {
+ bcopy((caddr_t) ina->x_host.c_host,
+ (caddr_t) sc->sc_enaddr,
+ sizeof(sc->sc_enaddr));
+ }
+
+ /*
+ * Set new address
+ */
+ fe_init(sc->sc_unit);
+ break;
+ }
+#endif
+#ifdef INET6
+ case AF_INET6:
+ /* IPV6 added by shin 96.2.6 */
+ fe_init(sc->sc_unit);
+ ndp6_ifinit(&sc->arpcom, ifa);
+ break;
+#endif
+#ifdef NS
+
+ /*
+ * XXX - This code is probably wrong
+ */
+ case AF_NS:
+ {
+ register struct ns_addr *ina
+ = &(IA_SNS(ifa)->sns_addr);
+
+ if (ns_nullhost(*ina))
+ ina->x_host =
+ *(union ns_host *) (sc->sc_enaddr);
+ else {
+ bcopy((caddr_t) ina->x_host.c_host,
+ (caddr_t) sc->sc_enaddr,
+ sizeof(sc->sc_enaddr));
+ }
+
+ /*
+ * Set new address
+ */
+ fe_init(sc->sc_unit);
+ break;
+ }
+#endif
+ default:
+ fe_init( sc->sc_unit );
+ break;
+ }
+ break;
+ }
+
+#ifdef SIOCGIFADDR
+ case SIOCGIFADDR:
+ {
+ struct ifreq * ifr = ( struct ifreq * )data;
+ struct sockaddr * sa = ( struct sockaddr * )&ifr->ifr_data;
+
+ bcopy((caddr_t)sc->sc_enaddr,
+ (caddr_t)sa->sa_data, ETHER_ADDR_LEN);
+ break;
+ }
+#endif
+
+#ifdef SIOCGIFPHYSADDR
+ case SIOCGIFPHYSADDR:
+ {
+ struct ifreq * ifr = ( struct ifreq * )data;
+
+ bcopy((caddr_t)sc->sc_enaddr,
+ (caddr_t)&ifr->ifr_data, ETHER_ADDR_LEN);
+ break;
+ }
+#endif
+
+#ifdef notdef
+#ifdef SIOCSIFPHYSADDR
+ case SIOCSIFPHYSADDR:
+ {
+ /*
+ * Set the physical (Ethernet) address of the interface.
+ * When and by whom is this command used? FIXME.
+ */
+ struct ifreq * ifr = ( struct ifreq * )data;
+
+ bcopy((caddr_t)&ifr->ifr_data,
+ (caddr_t)sc->sc_enaddr, ETHER_ADDR_LEN);
+ fe_setlinkaddr( sc );
+ break;
+ }
+#endif
+#endif /* notdef */
+
+#ifdef SIOCSIFFLAGS
+ case SIOCSIFFLAGS:
+ {
+ /*
+ * Switch interface state between "running" and
+ * "stopped", reflecting the UP flag.
+ */
+ if ( sc->sc_if.if_flags & IFF_UP ) {
+ if ( ( sc->sc_if.if_flags & IFF_RUNNING ) == 0 ) {
+ fe_init( sc->sc_unit );
+ }
+ } else {
+ if ( ( sc->sc_if.if_flags & IFF_RUNNING ) != 0 ) {
+ fe_stop( sc->sc_unit );
+ }
+ }
+
+ /*
+ * Promiscuous and/or multicast flags may have changed,
+ * so reprogram the multicast filter and/or receive mode.
+ */
+ fe_setmode( sc );
+
+#if FE_DEBUG >= 1
+ /* "ifconfig fe0 debug" to print register dump. */
+ if ( sc->sc_if.if_flags & IFF_DEBUG ) {
+ fe_dump( LOG_DEBUG, sc, "SIOCSIFFLAGS(DEBUG)" );
+ }
+#endif
+ break;
+ }
+#endif
+
+#ifdef SIOCADDMULTI
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ /*
+ * Multicast list has changed; set the hardware filter
+ * accordingly.
+ */
+ fe_setmode( sc );
+ error = 0;
+ break;
+#endif
+
+#ifdef SIOCSIFMTU
+ case SIOCSIFMTU:
+ {
+ /*
+ * Set the interface MTU.
+ */
+ struct ifreq * ifr = ( struct ifreq * )data;
+
+ if ( ifr->ifr_mtu > ETHERMTU ) {
+ error = EINVAL;
+ } else {
+ sc->sc_if.if_mtu = ifr->ifr_mtu;
+ }
+ break;
+ }
+#endif
+
+ default:
+ error = EINVAL;
+ }
+
+ (void) splx(s);
+ return (error);
+}
+
+/*
+ * Retrieve packet from receive buffer and send to the next level up via
+ * ether_input(). If there is a BPF listener, give a copy to BPF, too.
+ * Returns 0 if success, -1 if error (i.e., mbuf allocation failure).
+ */
+static int
+fe_get_packet ( struct fe_softc * sc, u_short len )
+{
+ struct ether_header *eh;
+ struct mbuf *m;
+
+ /*
+ * NFS wants the data be aligned to the word (4 byte)
+ * boundary. Ethernet header has 14 bytes. There is a
+ * 2-byte gap.
+ */
+#define NFS_MAGIC_OFFSET 2
+
+ /*
+ * This function assumes that an Ethernet packet fits in an
+ * mbuf (with a cluster attached when necessary.) On FreeBSD
+ * 2.0 for x86, which is the primary target of this driver, an
+ * mbuf cluster has 4096 bytes, and we are happy. On ancient
+ * BSDs, such as vanilla 4.3 for 386, a cluster size was 1024,
+ * however. If the following #error message were printed upon
+ * compile, you need to rewrite this function.
+ */
+#if ( MCLBYTES < ETHER_MAX_LEN - ETHER_CRC_LEN + NFS_MAGIC_OFFSET )
+#error "Too small MCLBYTES to use fe driver."
+#endif
+
+ /*
+ * Our strategy has one more problem. There is a policy on
+ * mbuf cluster allocation. It says that we must have at
+ * least MINCLSIZE (208 bytes on FreeBSD 2.0 for x86) to
+ * allocate a cluster. For a packet of a size between
+ * (MHLEN - 2) to (MINCLSIZE - 2), our code violates the rule...
+ * On the other hand, the current code is short, simple,
+ * and fast, however. It does no harmful thing, just waists
+ * some memory. Any comments? FIXME.
+ */
+
+ /* Allocate an mbuf with packet header info. */
+ MGETHDR(m, M_DONTWAIT, MT_DATA);
+ if ( m == NULL ) return -1;
+
+ /* Attach a cluster if this packet doesn't fit in a normal mbuf. */
+ if ( len > MHLEN - NFS_MAGIC_OFFSET ) {
+ MCLGET( m, M_DONTWAIT );
+ if ( !( m->m_flags & M_EXT ) ) {
+ m_freem( m );
+ return -1;
+ }
+ }
+
+ /* Initialize packet header info. */
+ m->m_pkthdr.rcvif = &sc->sc_if;
+ m->m_pkthdr.len = len;
+
+ /* Set the length of this packet. */
+ m->m_len = len;
+
+ /* The following silliness is to make NFS happy */
+ m->m_data += NFS_MAGIC_OFFSET;
+
+ /* Get a packet. */
+ insw( sc->ioaddr[ FE_BMPR8 ], m->m_data, ( len + 1 ) >> 1 );
+
+ /* Get (actually just point to) the header part. */
+ eh = mtod( m, struct ether_header *);
+
+#define ETHER_ADDR_IS_MULTICAST(A) (*(char *)(A) & 1)
+
+#if NBPFILTER > 0
+ /*
+ * Check if there's a BPF listener on this interface.
+ * If it is, hand off the raw packet to bpf.
+ */
+ if ( sc->sc_if.if_bpf ) {
+ bpf_mtap( &sc->sc_if, m );
+ }
+#endif
+
+ /*
+ * Make sure this packet is (or may be) directed to us.
+ * That is, the packet is either unicasted to our address,
+ * or broad/multi-casted. If any other packets are
+ * received, it is an indication of an error -- probably
+ * 86960 is in a wrong operation mode.
+ * Promiscuous mode is an exception. Under the mode, all
+ * packets on the media must be received. (We must have
+ * programmed the 86960 so.)
+ */
+
+ if ( ( sc->sc_if.if_flags & IFF_PROMISC )
+ && !ETHER_ADDR_IS_MULTICAST( eh->ether_dhost )
+ && bcmp( eh->ether_dhost, sc->sc_enaddr, ETHER_ADDR_LEN ) != 0 ) {
+ /*
+ * The packet was not for us. This is normal since
+ * we are now in promiscuous mode. Just drop the packet.
+ */
+ m_freem( m );
+ return 0;
+ }
+
+#if FE_DEBUG >= 3
+ if ( !ETHER_ADDR_IS_MULTICAST( eh->ether_dhost )
+ && bcmp( eh->ether_dhost, sc->sc_enaddr, ETHER_ADDR_LEN ) != 0 ) {
+ /*
+ * This packet was not for us. We can't be in promiscuous
+ * mode since the case was handled by above test.
+ * We found an error (of this driver.)
+ */
+ log( LOG_WARNING,
+ "fe%d: got an unwanted packet, dst = %6D\n",
+ sc->sc_unit, eh->ether_dhost , ":" );
+ m_freem( m );
+ return 0;
+ }
+#endif
+
+ /* Strip off the Ethernet header. */
+ m->m_pkthdr.len -= sizeof ( struct ether_header );
+ m->m_len -= sizeof ( struct ether_header );
+ m->m_data += sizeof ( struct ether_header );
+
+ /* Feed the packet to upper layer. */
+ ether_input( &sc->sc_if, eh, m );
+ return 0;
+}
+
+/*
+ * Write an mbuf chain to the transmission buffer memory using 16 bit PIO.
+ * Returns number of bytes actually written, including length word.
+ *
+ * If an mbuf chain is too long for an Ethernet frame, it is not sent.
+ * Packets shorter than Ethernet minimum are legal, and we pad them
+ * before sending out. An exception is "partial" packets which are
+ * shorter than mandatory Ethernet header.
+ */
+static void
+fe_write_mbufs ( struct fe_softc *sc, struct mbuf *m )
+{
+ u_short addr_bmpr8 = sc->ioaddr[ FE_BMPR8 ];
+ u_short length, len;
+ struct mbuf *mp;
+ u_char *data;
+ u_short savebyte; /* WARNING: Architecture dependent! */
+#define NO_PENDING_BYTE 0xFFFF
+
+ static u_char padding [ ETHER_MIN_LEN - ETHER_CRC_LEN - ETHER_HDR_LEN ];
+
+#if FE_DEBUG >= 1
+ /* First, count up the total number of bytes to copy */
+ length = 0;
+ for ( mp = m; mp != NULL; mp = mp->m_next ) {
+ length += mp->m_len;
+ }
+#else
+ /* Just use the length value in the packet header. */
+ length = m->m_pkthdr.len;
+#endif
+
+#if FE_DEBUG >= 2
+ /* Check if this matches the one in the packet header. */
+ if ( length != m->m_pkthdr.len ) {
+ log( LOG_WARNING, "fe%d: packet length mismatch? (%d/%d)\n",
+ sc->sc_unit, length, m->m_pkthdr.len );
+ }
+#endif
+
+#if FE_DEBUG >= 1
+ /*
+ * Should never send big packets. If such a packet is passed,
+ * it should be a bug of upper layer. We just ignore it.
+ * ... Partial (too short) packets, neither.
+ */
+ if ( length < ETHER_HDR_LEN
+ || length > ETHER_MAX_LEN - ETHER_CRC_LEN ) {
+ log( LOG_ERR,
+ "fe%d: got an out-of-spec packet (%u bytes) to send\n",
+ sc->sc_unit, length );
+ sc->sc_if.if_oerrors++;
+ return;
+ }
+#endif
+
+ /*
+ * Put the length word for this frame.
+ * Does 86960 accept odd length? -- Yes.
+ * Do we need to pad the length to minimum size by ourselves?
+ * -- Generally yes. But for (or will be) the last
+ * packet in the transmission buffer, we can skip the
+ * padding process. It may gain performance slightly. FIXME.
+ */
+ outw( addr_bmpr8, max( length, ETHER_MIN_LEN - ETHER_CRC_LEN ) );
+
+ /*
+ * Update buffer status now.
+ * Truncate the length up to an even number, since we use outw().
+ */
+ length = ( length + 1 ) & ~1;
+ sc->txb_free -= FE_DATA_LEN_LEN + max( length, ETHER_MIN_LEN - ETHER_CRC_LEN);
+ sc->txb_count++;
+
+ /*
+ * Transfer the data from mbuf chain to the transmission buffer.
+ * MB86960 seems to require that data be transferred as words, and
+ * only words. So that we require some extra code to patch
+ * over odd-length mbufs.
+ */
+ savebyte = NO_PENDING_BYTE;
+ for ( mp = m; mp != 0; mp = mp->m_next ) {
+
+ /* Ignore empty mbuf. */
+ len = mp->m_len;
+ if ( len == 0 ) continue;
+
+ /* Find the actual data to send. */
+ data = mtod(mp, caddr_t);
+
+ /* Finish the last byte. */
+ if ( savebyte != NO_PENDING_BYTE ) {
+ outw( addr_bmpr8, savebyte | ( *data << 8 ) );
+ data++;
+ len--;
+ savebyte = NO_PENDING_BYTE;
+ }
+
+ /* output contiguous words */
+ if (len > 1) {
+ outsw( addr_bmpr8, data, len >> 1);
+ data += len & ~1;
+ len &= 1;
+ }
+
+ /* Save a remaining byte, if there is one. */
+ if ( len > 0 ) {
+ savebyte = *data;
+ }
+ }
+
+ /* Spit the last byte, if the length is odd. */
+ if ( savebyte != NO_PENDING_BYTE ) {
+ outw( addr_bmpr8, savebyte );
+ }
+
+ /* Pad to the Ethernet minimum length, if the packet is too short. */
+ if ( length < ETHER_MIN_LEN - ETHER_CRC_LEN ) {
+ outsw( addr_bmpr8, padding, ( ETHER_MIN_LEN - ETHER_CRC_LEN - length ) >> 1);
+ }
+}
+
+/*
+ * Compute hash value for an Ethernet address
+ */
+static int
+fe_hash ( u_char * ep )
+{
+#define FE_HASH_MAGIC_NUMBER 0xEDB88320L
+
+ u_long hash = 0xFFFFFFFFL;
+ int i, j;
+ u_char b;
+ u_long m;
+
+ for ( i = ETHER_ADDR_LEN; --i >= 0; ) {
+ b = *ep++;
+ for ( j = 8; --j >= 0; ) {
+ m = hash;
+ hash >>= 1;
+ if ( ( m ^ b ) & 1 ) hash ^= FE_HASH_MAGIC_NUMBER;
+ b >>= 1;
+ }
+ }
+ return ( ( int )( hash >> 26 ) );
+}
+
+/*
+ * Compute the multicast address filter from the
+ * list of multicast addresses we need to listen to.
+ */
+static struct fe_filter
+fe_mcaf ( struct fe_softc *sc )
+{
+ int index;
+ struct fe_filter filter;
+ struct ifmultiaddr *ifma;
+
+ filter = fe_filter_nothing;
+ for (ifma = sc->arpcom.ac_if.if_multiaddrs.lh_first; ifma;
+ ifma = ifma->ifma_link.le_next) {
+ if (ifma->ifma_addr->sa_family != AF_LINK)
+ continue;
+ index = fe_hash(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
+#if FE_DEBUG >= 4
+ log( LOG_INFO, "fe%d: hash(%6D) == %d\n",
+ sc->sc_unit, enm->enm_addrlo , ":", index );
+#endif
+
+ filter.data[index >> 3] |= 1 << (index & 7);
+ }
+ return ( filter );
+}
+
+/*
+ * Calculate a new "multicast packet filter" and put the 86960
+ * receiver in appropriate mode.
+ */
+static void
+fe_setmode ( struct fe_softc *sc )
+{
+ int flags = sc->sc_if.if_flags;
+
+ /*
+ * If the interface is not running, we postpone the update
+ * process for receive modes and multicast address filter
+ * until the interface is restarted. It reduces some
+ * complicated job on maintaining chip states. (Earlier versions
+ * of this driver had a bug on that point...)
+ *
+ * To complete the trick, fe_init() calls fe_setmode() after
+ * restarting the interface.
+ */
+ if ( !( flags & IFF_RUNNING ) ) return;
+
+ /*
+ * Promiscuous mode is handled separately.
+ */
+ if ( flags & IFF_PROMISC ) {
+ /*
+ * Program 86960 to receive all packets on the segment
+ * including those directed to other stations.
+ * Multicast filter stored in MARs are ignored
+ * under this setting, so we don't need to update it.
+ *
+ * Promiscuous mode in FreeBSD 2 is used solely by
+ * BPF, and BPF only listens to valid (no error) packets.
+ * So, we ignore erroneous ones even in this mode.
+ * (Older versions of fe driver mistook the point.)
+ */
+ outb( sc->ioaddr[ FE_DLCR5 ],
+ sc->proto_dlcr5 | FE_D5_AFM0 | FE_D5_AFM1 );
+ sc->filter_change = 0;
+
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: promiscuous mode\n", sc->sc_unit );
+#endif
+ return;
+ }
+
+ /*
+ * Turn the chip to the normal (non-promiscuous) mode.
+ */
+ outb( sc->ioaddr[ FE_DLCR5 ], sc->proto_dlcr5 | FE_D5_AFM1 );
+
+ /*
+ * Find the new multicast filter value.
+ * I'm not sure we have to handle modes other than MULTICAST.
+ * Who sets ALLMULTI? Who turns MULTICAST off? FIXME.
+ */
+ if ( flags & IFF_ALLMULTI ) {
+ sc->filter = fe_filter_all;
+ } else if ( flags & IFF_MULTICAST ) {
+ sc->filter = fe_mcaf( sc );
+ } else {
+ sc->filter = fe_filter_nothing;
+ }
+ sc->filter_change = 1;
+
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: address filter: [%8D]\n",
+ sc->sc_unit, sc->filter.data, " " );
+#endif
+
+ /*
+ * We have to update the multicast filter in the 86960, A.S.A.P.
+ *
+ * Note that the DLC (Data Link Control unit, i.e. transmitter
+ * and receiver) must be stopped when feeding the filter, and
+ * DLC trashes all packets in both transmission and receive
+ * buffers when stopped.
+ *
+ * ... Are the above sentences correct? I have to check the
+ * manual of the MB86960A. FIXME.
+ *
+ * To reduce the packet loss, we delay the filter update
+ * process until buffers are empty.
+ */
+ if ( sc->txb_sched == 0 && sc->txb_count == 0
+ && !( inb( sc->ioaddr[ FE_DLCR1 ] ) & FE_D1_PKTRDY ) ) {
+ /*
+ * Buffers are (apparently) empty. Load
+ * the new filter value into MARs now.
+ */
+ fe_loadmar(sc);
+ } else {
+ /*
+ * Buffers are not empty. Mark that we have to update
+ * the MARs. The new filter will be loaded by feintr()
+ * later.
+ */
+#if FE_DEBUG >= 4
+ log( LOG_INFO, "fe%d: filter change delayed\n", sc->sc_unit );
+#endif
+ }
+}
+
+/*
+ * Load a new multicast address filter into MARs.
+ *
+ * The caller must have splimp'ed before fe_loadmar.
+ * This function starts the DLC upon return. So it can be called only
+ * when the chip is working, i.e., from the driver's point of view, when
+ * a device is RUNNING. (I mistook the point in previous versions.)
+ */
+static void
+fe_loadmar ( struct fe_softc * sc )
+{
+ /* Stop the DLC (transmitter and receiver). */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_DISABLE );
+ DELAY( 200 );
+
+ /* Select register bank 1 for MARs. */
+ outb( sc->ioaddr[ FE_DLCR7 ],
+ sc->proto_dlcr7 | FE_D7_RBS_MAR | FE_D7_POWER_UP );
+
+ /* Copy filter value into the registers. */
+ outblk( sc, FE_MAR8, sc->filter.data, FE_FILTER_LEN );
+
+ /* Restore the bank selection for BMPRs (i.e., runtime registers). */
+ outb( sc->ioaddr[ FE_DLCR7 ],
+ sc->proto_dlcr7 | FE_D7_RBS_BMPR | FE_D7_POWER_UP );
+
+ /* Restart the DLC. */
+ DELAY( 200 );
+ outb( sc->ioaddr[ FE_DLCR6 ], sc->proto_dlcr6 | FE_D6_DLC_ENABLE );
+ DELAY( 200 );
+
+ /* We have just updated the filter. */
+ sc->filter_change = 0;
+
+#if FE_DEBUG >= 3
+ log( LOG_INFO, "fe%d: address filter changed\n", sc->sc_unit );
+#endif
+}
+
+#if FE_DEBUG >= 1
+static void
+fe_dump ( int level, struct fe_softc * sc, char * message )
+{
+ log( level, "fe%d: %s,"
+ " DLCR = %02x %02x %02x %02x %02x %02x %02x %02x,"
+ " BMPR = xx xx %02x %02x %02x %02x %02x %02x,"
+ " asic = %02x %02x %02x %02x %02x %02x %02x %02x"
+ " + %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ sc->sc_unit, message ? message : "registers",
+ inb( sc->ioaddr[ FE_DLCR0 ] ), inb( sc->ioaddr[ FE_DLCR1 ] ),
+ inb( sc->ioaddr[ FE_DLCR2 ] ), inb( sc->ioaddr[ FE_DLCR3 ] ),
+ inb( sc->ioaddr[ FE_DLCR4 ] ), inb( sc->ioaddr[ FE_DLCR5 ] ),
+ inb( sc->ioaddr[ FE_DLCR6 ] ), inb( sc->ioaddr[ FE_DLCR7 ] ),
+ inb( sc->ioaddr[ FE_BMPR10 ] ), inb( sc->ioaddr[ FE_BMPR11 ] ),
+ inb( sc->ioaddr[ FE_BMPR12 ] ), inb( sc->ioaddr[ FE_BMPR13 ] ),
+ inb( sc->ioaddr[ FE_BMPR14 ] ), inb( sc->ioaddr[ FE_BMPR15 ] ),
+ inb( sc->ioaddr[ 0x10 ] ), inb( sc->ioaddr[ 0x11 ] ),
+ inb( sc->ioaddr[ 0x12 ] ), inb( sc->ioaddr[ 0x13 ] ),
+ inb( sc->ioaddr[ 0x14 ] ), inb( sc->ioaddr[ 0x15 ] ),
+ inb( sc->ioaddr[ 0x16 ] ), inb( sc->ioaddr[ 0x17 ] ),
+ inb( sc->ioaddr[ 0x18 ] ), inb( sc->ioaddr[ 0x19 ] ),
+ inb( sc->ioaddr[ 0x1A ] ), inb( sc->ioaddr[ 0x1B ] ),
+ inb( sc->ioaddr[ 0x1C ] ), inb( sc->ioaddr[ 0x1D ] ),
+ inb( sc->ioaddr[ 0x1E ] ), inb( sc->ioaddr[ 0x1F ] ) );
+}
+#endif
diff --git a/sys/pc98/pc98/lpt.c b/sys/pc98/pc98/lpt.c
index 856974f65f84..1fac3d86e58c 100644
--- a/sys/pc98/pc98/lpt.c
+++ b/sys/pc98/pc98/lpt.c
@@ -46,7 +46,7 @@
* SUCH DAMAGE.
*
* from: unknown origin, 386BSD 0.1
- * $Id: lpt.c,v 1.23 1998/10/22 05:58:45 bde Exp $
+ * $Id: lpt.c,v 1.21 1998/06/17 16:33:14 kato Exp $
*/
/*
@@ -195,12 +195,9 @@
#ifndef DEBUG
-#define lprintf(args)
+#define lprintf (void)
#else
-#define lprintf(args) do { \
- if (lptflag) \
- printf args; \
- } while (0)
+#define lprintf if (lptflag) printf
static int volatile lptflag = 1;
#endif
@@ -272,7 +269,6 @@ static struct lpt_softc {
static timeout_t lptout;
static int lptprobe (struct isa_device *dvp);
static int lptattach (struct isa_device *isdp);
-static ointhand2_t lptintr;
#ifdef INET
@@ -328,8 +324,8 @@ lpt_port_test (int port, u_char data, u_char mask)
temp = inb(port) & mask;
}
while (temp != data && --timeout);
- lprintf(("Port 0x%x\tout=%x\tin=%x\ttout=%d\n",
- port, data, temp, timeout));
+ lprintf("Port 0x%x\tout=%x\tin=%x\ttout=%d\n",
+ port, data, temp, timeout);
return (temp == data);
}
@@ -441,7 +437,6 @@ lptattach(struct isa_device *isdp)
struct lpt_softc *sc;
int unit;
- isdp->id_ointr = lptintr;
unit = isdp->id_unit;
sc = lpt_sc + unit;
sc->sc_port = isdp->id_iobase;
@@ -457,7 +452,7 @@ lptattach(struct isa_device *isdp)
#endif
/* check if we can use interrupt */
- lprintf(("oldirq %x\n", sc->sc_irq));
+ lprintf("oldirq %x\n", sc->sc_irq);
if (isdp->id_irq) {
sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
printf("lpt%d: Interrupt-driven port\n", unit);
@@ -466,9 +461,9 @@ lptattach(struct isa_device *isdp)
#endif
} else {
sc->sc_irq = 0;
- lprintf(("lpt%d: Polled port\n", unit));
+ lprintf("lpt%d: Polled port\n", unit);
}
- lprintf(("irq %x\n", sc->sc_irq));
+ lprintf("irq %x\n", sc->sc_irq);
#ifdef DEVFS
/* XXX what to do about the flags in the minor number? */
@@ -506,7 +501,7 @@ lptopen (dev_t dev, int flags, int fmt, struct proc *p)
#endif
if (sc->sc_state) {
- lprintf(("lp: still open %x\n", sc->sc_state));
+ lprintf("lp: still open %x\n", sc->sc_state);
return(EBUSY);
} else
sc->sc_state |= INIT;
@@ -520,7 +515,7 @@ lptopen (dev_t dev, int flags, int fmt, struct proc *p)
}
s = spltty();
- lprintf(("lp flags 0x%x\n", sc->sc_flags));
+ lprintf("lp flags 0x%x\n", sc->sc_flags);
port = sc->sc_port;
/* set IRQ status according to ENABLE_IRQ flag */
@@ -548,7 +543,7 @@ lptopen (dev_t dev, int flags, int fmt, struct proc *p)
if (trys++ >= LPINITRDY*4) {
splx(s);
sc->sc_state = 0;
- lprintf(("status %x\n", inb(port+lpt_status)));
+ lprintf ("status %x\n", inb(port+lpt_status) );
return (EBUSY);
}
@@ -581,14 +576,14 @@ lptopen (dev_t dev, int flags, int fmt, struct proc *p)
splx(s);
/* only use timeout if using interrupt */
- lprintf(("irq %x\n", sc->sc_irq));
+ lprintf("irq %x\n", sc->sc_irq);
if (sc->sc_irq & LP_USE_IRQ) {
sc->sc_state |= TOUT;
timeout (lptout, (caddr_t)sc,
(sc->sc_backoff = hz/LPTOUTINITIAL));
}
- lprintf(("opened.\n"));
+ lprintf("opened.\n");
return(0);
}
@@ -598,7 +593,7 @@ lptout (void *arg)
struct lpt_softc *sc = arg;
int pl;
- lprintf(("T %x ", inb(sc->sc_port+lpt_status)));
+ lprintf ("T %x ", inb(sc->sc_port+lpt_status));
if (sc->sc_state & OPEN) {
sc->sc_backoff++;
if (sc->sc_backoff > hz/LPTOUTMAX)
@@ -657,7 +652,7 @@ lptclose(dev_t dev, int flags, int fmt, struct proc *p)
end_close:
sc->sc_state = 0;
sc->sc_xfercnt = 0;
- lprintf(("closed.\n"));
+ lprintf("closed.\n");
return(0);
}
@@ -676,7 +671,7 @@ pushbytes(struct lpt_softc * sc)
char ch;
int port = sc->sc_port;
- lprintf(("p"));
+ lprintf("p");
/* loop for every character .. */
while (sc->sc_xfercnt > 0) {
/* printer data */
@@ -754,16 +749,16 @@ lptwrite(dev_t dev, struct uio * uio, int ioflag)
uiomove(sc->sc_cp, n, uio);
sc->sc_xfercnt = n ;
while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) {
- lprintf(("i"));
+ lprintf("i");
/* if the printer is ready for a char, */
/* give it one */
if ((sc->sc_state & OBUSY) == 0){
- lprintf(("\nC %d. ", sc->sc_xfercnt));
+ lprintf("\nC %d. ", sc->sc_xfercnt);
pl = spltty();
lptintr(sc - lpt_sc);
(void) splx(pl);
}
- lprintf(("W "));
+ lprintf("W ");
if (sc->sc_state & OBUSY)
if ((err = tsleep ((caddr_t)sc,
LPPRI|PCATCH, "lpwrite", 0))) {
@@ -773,7 +768,7 @@ lptwrite(dev_t dev, struct uio * uio, int ioflag)
}
/* check to see if we must do a polled write */
if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) {
- lprintf(("p"));
+ lprintf("p");
if((err = pushbytes(sc)))
return(err);
}
@@ -788,7 +783,7 @@ lptwrite(dev_t dev, struct uio * uio, int ioflag)
* do checking for interrupted write call.
*/
-static void
+void
lptintr(int unit)
{
struct lpt_softc *sc = lpt_sc + unit;
@@ -819,7 +814,7 @@ lptintr(int unit)
if (sc->sc_xfercnt) {
/* send char */
- /*lprintf(("%x ", *sc->sc_cp)); */
+ /*lprintf("%x ", *sc->sc_cp); */
outb(port+lpt_data, *sc->sc_cp++) ;
outb(port+lpt_control, sc->sc_control|LPC_STB);
/* DELAY(X) */
@@ -836,7 +831,7 @@ lptintr(int unit)
sc->sc_state &= ~OBUSY;
if(!(sc->sc_state & INTERRUPTED))
wakeup((caddr_t)sc);
- lprintf(("w "));
+ lprintf("w ");
return;
} else { /* check for error */
if(((sts & (LPS_NERR | LPS_OUT) ) != LPS_NERR) &&
@@ -845,7 +840,7 @@ lptintr(int unit)
/* lptout() will jump in and try to restart. */
}
#endif
- lprintf(("sts %x ", sts));
+ lprintf("sts %x ", sts);
}
static int
@@ -1032,7 +1027,7 @@ lpioctl (struct ifnet *ifp, u_long cmd, caddr_t data)
break;
default:
- lprintf(("LP:ioctl(0x%lx)\n", cmd));
+ lprintf("LP:ioctl(0x%lx)\n", cmd);
return EINVAL;
}
return 0;
@@ -1129,7 +1124,7 @@ lpintr (int unit)
sc->sc_iferrs = 0;
if (IF_QFULL(&ipintrq)) {
- lprintf(("DROP"));
+ lprintf("DROP");
IF_DROP(&ipintrq);
goto done;
}
@@ -1178,7 +1173,7 @@ lpintr (int unit)
sc->sc_iferrs = 0;
if (IF_QFULL(&ipintrq)) {
- lprintf(("DROP"));
+ lprintf("DROP");
IF_DROP(&ipintrq);
goto done;
}
@@ -1200,7 +1195,7 @@ lpintr (int unit)
err:
outb(lpt_data_port, 0);
- lprintf(("R"));
+ lprintf("R");
sc->sc_if.if_ierrors++;
sc->sc_iferrs++;
@@ -1266,7 +1261,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
if (ifp->if_flags & IFF_LINK0) {
if (!(inb(lpt_stat_port) & CLPIP_SHAKE)) {
- lprintf(("&"));
+ lprintf("&");
lptintr(ifp->if_unit);
}
@@ -1326,7 +1321,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
nend:
if (err) { /* if we didn't timeout... */
ifp->if_oerrors++;
- lprintf(("X"));
+ lprintf("X");
} else {
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
@@ -1335,7 +1330,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
m_freem(m);
if (!(inb(lpt_stat_port) & CLPIP_SHAKE)) {
- lprintf(("^"));
+ lprintf("^");
lptintr(ifp->if_unit);
}
(void) splx(s);
@@ -1343,7 +1338,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
}
if (inb(lpt_stat_port) & LPIP_SHAKE) {
- lprintf(("&"));
+ lprintf("&");
lptintr(ifp->if_unit);
}
@@ -1368,7 +1363,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
if (err) { /* if we didn't timeout... */
ifp->if_oerrors++;
- lprintf(("X"));
+ lprintf("X");
} else {
ifp->if_opackets++;
ifp->if_obytes += m->m_pkthdr.len;
@@ -1396,7 +1391,7 @@ lpoutput (struct ifnet *ifp, struct mbuf *m,
m_freem(m);
if (inb(lpt_stat_port) & LPIP_SHAKE) {
- lprintf(("^"));
+ lprintf("^");
lptintr(ifp->if_unit);
}
diff --git a/sys/pc98/pc98/mse.c b/sys/pc98/pc98/mse.c
index e5bcc4439bf8..65a8aa5bc858 100644
--- a/sys/pc98/pc98/mse.c
+++ b/sys/pc98/pc98/mse.c
@@ -11,7 +11,7 @@
* this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
- * $Id: mse.c,v 1.17 1998/06/08 08:55:44 kato Exp $
+ * $Id: mse.c,v 1.16 1998/01/24 02:54:38 eivind Exp $
*/
/*
* Driver for the Logitech and ATI Inport Bus mice for use with 386bsd and
@@ -88,7 +88,6 @@ static struct cdevsw mse_cdevsw =
mseioctl, nostop, nullreset, nodevtotty,/* mse */
msepoll, nommap, NULL, "mse", NULL, -1 };
-static ointhand2_t mseintr;
/*
* Software control structure for mouse. The sc_enablemouse(),
@@ -322,7 +321,6 @@ mseattach(idp)
}
#endif
- idp->id_ointr = mseintr;
sc->sc_port = idp->id_iobase;
sc->mode.accelfactor = (idp->id_flags & MSE_CONFIG_ACCEL) >> 4;
#ifdef DEVFS
@@ -612,7 +610,7 @@ msepoll(dev, events, p)
/*
* mseintr: update mouse status. sc_deltax and sc_deltay are accumulative.
*/
-static void
+void
mseintr(unit)
int unit;
{
diff --git a/sys/pc98/pc98/npx.c b/sys/pc98/pc98/npx.c
index 03077ddfb565..504fd3cf506e 100644
--- a/sys/pc98/pc98/npx.c
+++ b/sys/pc98/pc98/npx.c
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
- * $Id: npx.c,v 1.41 1998/12/17 08:41:34 kato Exp $
+ * $Id: npx.c,v 1.37 1998/05/04 07:33:32 kato Exp $
*/
#include "npx.h"
@@ -59,7 +59,9 @@
#include <machine/cputypes.h>
#include <machine/frame.h>
#include <machine/ipl.h>
+#ifndef SMP
#include <machine/md_var.h>
+#endif
#include <machine/pcb.h>
#include <machine/psl.h>
#ifndef SMP
@@ -89,7 +91,15 @@
#define NPX_DISABLE_I586_OPTIMIZED_COPYIO (1 << 2)
/* XXX - should be in header file. */
-ointhand2_t npxintr;
+extern void (*bcopy_vector) __P((const void *from, void *to, size_t len));
+extern void (*ovbcopy_vector) __P((const void *from, void *to, size_t len));
+extern int (*copyin_vector) __P((const void *udaddr, void *kaddr, size_t len));
+extern int (*copyout_vector) __P((const void *kaddr, void *udaddr, size_t len));
+
+void i586_bcopy __P((const void *from, void *to, size_t len));
+void i586_bzero __P((void *buf, size_t len));
+int i586_copyin __P((const void *udaddr, void *kaddr, size_t len));
+int i586_copyout __P((const void *kaddr, void *udaddr, size_t len));
#ifdef __GNUC__
@@ -140,17 +150,15 @@ SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
CTLFLAG_RD, &hw_float, 0,
"Floatingpoint instructions executed in hardware");
-#ifndef SMP
-static u_int npx0_imask = SWI_CLOCK_MASK;
-static struct gate_descriptor npx_idt_probeintr;
-static int npx_intrno;
-static volatile u_int npx_intrs_while_probing;
-static volatile u_int npx_traps_while_probing;
-#endif
+static u_int npx0_imask = SWI_CLOCK_MASK;
static bool_t npx_ex16;
static bool_t npx_exists;
+static struct gate_descriptor npx_idt_probeintr;
+static int npx_intrno;
+static volatile u_int npx_intrs_while_probing;
static bool_t npx_irq13;
+static volatile u_int npx_traps_while_probing;
#ifndef SMP
/*
@@ -270,10 +278,8 @@ static int
npxprobe1(dvp)
struct isa_device *dvp;
{
-#ifndef SMP
u_short control;
u_short status;
-#endif
/*
* Partially reset the coprocessor, if any. Some BIOS's don't reset
@@ -421,8 +427,6 @@ int
npxattach(dvp)
struct isa_device *dvp;
{
- dvp->id_ointr = npxintr;
-
/* The caller has printed "irq 13" for the npx_irq13 case. */
if (!npx_irq13) {
printf("npx%d: ", dvp->id_unit);
diff --git a/sys/pc98/pc98/pc98.c b/sys/pc98/pc98/pc98.c
index a3c9bc36c214..185c34906674 100644
--- a/sys/pc98/pc98/pc98.c
+++ b/sys/pc98/pc98/pc98.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id: pc98.c,v 1.54 1998/10/22 05:58:45 bde Exp $
+ * $Id: pc98.c,v 1.52 1998/10/12 15:06:02 kato Exp $
*/
/*
@@ -535,7 +535,7 @@ config_isadev_c(isdp, mp, reconfig)
printf("%s%d", dp->name, isdp->id_unit);
if (id_alive != -1) {
if (isdp->id_iobase == -1)
- printf(" at");
+ printf(" at ?");
else {
printf(" at 0x%x", isdp->id_iobase);
if (isdp->id_iobase + id_alive - 1 !=
@@ -583,10 +583,7 @@ config_isadev_c(isdp, mp, reconfig)
isdp->id_alive = id_alive;
}
(*dp->attach)(isdp);
- if (isdp->id_irq != 0 && isdp->id_intr == NULL)
- printf("%s%d: irq with no handler\n",
- dp->name, isdp->id_unit);
- if (isdp->id_irq != 0 && isdp->id_intr != NULL) {
+ if (isdp->id_irq) {
#ifdef APIC_IO
/*
* Some motherboards use upper IRQs for traditional
@@ -623,7 +620,7 @@ config_isadev_c(isdp, mp, reconfig)
} else {
#if 0
/* This code has not been tested.... */
- if (isdp->id_irq != 0 && isdp->id_intr != NULL) {
+ if (isdp->id_irq) {
icu_unset(ffs(isdp->id_irq) - 1,
isdp->id_intr);
if (mp)
diff --git a/sys/pc98/pc98/pc98gdc.c b/sys/pc98/pc98/pc98gdc.c
deleted file mode 100644
index 076f9e774882..000000000000
--- a/sys/pc98/pc98/pc98gdc.c
+++ /dev/null
@@ -1,887 +0,0 @@
-/*
- * Copyright (c) 1999 FreeBSD(98) port team.
- * 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 as
- * the first lines of this file unmodified.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id$
- */
-
-#include "gdc.h"
-#include "opt_gdc.h"
-#include "opt_fb.h"
-#include "opt_syscons.h"
-
-#if NGDC > 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
-#include <machine/console.h>
-#include <machine/md_var.h>
-#include <machine/pc/bios.h>
-
-#include <dev/fb/fbreg.h>
-
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/pc98_machdep.h>
-
-#include <i386/isa/isa_device.h>
-
-#define TEXT_GDC IO_GDC1 /* 0x60 */
-#define ROW 25
-#define COL 80
-
-#define DRIVER_NAME "gdc"
-
-/* cdev driver declaration */
-
-#define GDC_UNIT(dev) minor(dev)
-#define GDC_MKMINOR(unit) (unit)
-
-static int gdcprobe(struct isa_device *dev);
-static int gdc_attach(struct isa_device *dev);
-static void gdc_drvinit(void *unused);
-
-struct isa_driver gdcdriver = {
- gdcprobe,
- gdc_attach,
- DRIVER_NAME,
- 0,
-};
-
-typedef struct gdc_softc {
- video_adapter_t *adp;
-} gdc_softc_t;
-
-static int gdc_probe_unit(int unit, gdc_softc_t *sc, int flags);
-static int gdc_attach_unit(int unit, gdc_softc_t *sc, int flags);
-
-#define GDC_SOFTC(unit) (gdc_softc[unit])
-
-static gdc_softc_t *gdc_softc[NGDC];
-
-#if FB_INSTALL_CDEV
-
-static d_open_t gdcopen;
-static d_close_t gdcclose;
-static d_read_t gdcread;
-static d_ioctl_t gdcioctl;
-
-static struct cdevsw vga_cdevsw = {
- gdcopen, gdcclose, noread, nowrite, /* ?? */
- gdcioctl, nostop, nullreset, nodevtotty,
- seltrue, nommap, NULL, DRIVER_NAME,
- NULL, -1, nodump, nopsize,
-};
-
-#endif /* FB_INSTALL_CDEV */
-
-static int
-gdcprobe(struct isa_device *dev)
-{
- gdc_softc_t *sc;
- int error;
-
- if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
- return 0;
- sc = gdc_softc[dev->id_unit]
- = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
- if (sc == NULL)
- return 0;
-
- error = gdc_probe_unit(dev->id_unit, sc, dev->id_flags);
- if (error) {
- gdc_softc[dev->id_unit] = NULL;
- free(sc, M_DEVBUF);
- return 0;
- }
-
- dev->id_iobase = sc->adp->va_io_base;
- dev->id_maddr = (caddr_t)BIOS_PADDRTOVADDR(sc->adp->va_mem_base);
- dev->id_msize = sc->adp->va_mem_size;
-
- return sc->adp->va_io_size;
-}
-
-static int
-gdc_attach(struct isa_device *dev)
-{
- gdc_softc_t *sc;
-
- if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
- return 0;
- sc = gdc_softc[dev->id_unit];
- if (sc == NULL)
- return 0;
-
- return ((gdc_attach_unit(dev->id_unit, sc, dev->id_flags)) ? 0 : 1);
-}
-
-static int
-gdc_probe_unit(int unit, gdc_softc_t *sc, int flags)
-{
- video_switch_t *sw;
-
- bzero(sc, sizeof(*sc));
- sw = vid_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return 0;
- return (*sw->probe)(unit, &sc->adp, NULL, flags);
-}
-
-static int
-gdc_attach_unit(int unit, gdc_softc_t *sc, int flags)
-{
- video_switch_t *sw;
- int error;
-
- sw = vid_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
-
- error = (*sw->init)(unit, sc->adp, flags);
- if (error)
- return ENXIO;
-
-#ifdef FB_INSTALL_CDEV
- /* attach a virtual frame buffer device */
- error = fb_attach(makedev(0, GDC_MKMINOR(unit)), scp->adp,
- &vga_cdevsw);
- if (error)
- return error;
-#endif /* FB_INSTALL_CDEV */
-
- if (bootverbose)
- (*sw->diag)(sc->adp, bootverbose);
-
- return 0;
-}
-
-/* LOW-LEVEL */
-
-#include <machine/clock.h>
-
-#include <pc98/pc98/30line.h>
-
-#define TEXT_BUF_BASE 0x000a0000
-#define TEXT_BUF_SIZE 0x00008000
-#define GRAPHICS_BUF_BASE 0x000a8000
-#define GRAPHICS_BUF_SIZE 0x00040000
-#define VIDEO_BUF_BASE 0x000a0000
-#define VIDEO_BUF_SIZE 0x00048000
-
-#define probe_done(adp) ((adp)->va_flags & V_ADP_PROBED)
-#define init_done(adp) ((adp)->va_flags & V_ADP_INITIALIZED)
-#define config_done(adp) ((adp)->va_flags & V_ADP_REGISTERED)
-
-/*
- * NOTE: `va_window' should have a virtual address, but is initialized
- * with a physical address in the following table, they will be
- * converted at run-time.
- */
-static video_adapter_t adapter_init_value[] = {
- { 0,
- KD_PC98, "gdc", /* va_type, va_name */
- 0, 0, /* va_unit, va_minor */
- V_ADP_COLOR | V_ADP_MODECHANGE | V_ADP_BORDER,
- IO_GDC1, 16, TEXT_GDC, /* va_io*, XXX */
- VIDEO_BUF_BASE, VIDEO_BUF_SIZE, /* va_mem* */
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, /* va_window* */
- 0, 0, /* va_buffer, va_buffer_size */
- 0, M_PC98_80x25, 0, 0, /* va_*mode* */
- NULL },
-};
-
-static video_adapter_t biosadapter[1];
-
-/* video driver declarations */
-static int gdc_configure(int flags);
-static int gdc_nop(void);
-static vi_probe_t gdc_probe;
-static vi_init_t gdc_init;
-static vi_get_info_t gdc_get_info;
-static vi_query_mode_t gdc_query_mode;
-static vi_set_mode_t gdc_set_mode;
-static vi_set_border_t gdc_set_border;
-static vi_save_state_t gdc_save_state;
-static vi_load_state_t gdc_load_state;
-static vi_read_hw_cursor_t gdc_read_hw_cursor;
-static vi_set_hw_cursor_t gdc_set_hw_cursor;
-static vi_set_hw_cursor_shape_t gdc_set_hw_cursor_shape;
-static vi_mmap_t gdc_mmap;
-static vi_diag_t gdc_diag;
-
-static int gdc_err(video_adapter_t *adp, ...);
-
-static video_switch_t gdcvidsw = {
- gdc_probe,
- gdc_init,
- gdc_get_info,
- gdc_query_mode,
- gdc_set_mode,
- (vi_save_font_t *)gdc_err,
- (vi_load_font_t *)gdc_err,
- (vi_show_font_t *)gdc_err,
- (vi_save_palette_t *)gdc_err,
- (vi_load_palette_t *)gdc_err,
- gdc_set_border,
- gdc_save_state,
- gdc_load_state,
- (vi_set_win_org_t *)gdc_err,
- gdc_read_hw_cursor,
- gdc_set_hw_cursor,
- gdc_set_hw_cursor_shape,
- (vi_blank_display_t *)gdc_nop,
- gdc_mmap,
- gdc_diag,
-};
-
-VIDEO_DRIVER(gdc, gdcvidsw, gdc_configure);
-
-/* GDC BIOS standard video modes */
-#define EOT (-1)
-#define NA (-2)
-
-static video_info_t bios_vmode[] = {
- { M_PC98_80x25, V_INFO_COLOR, 80, 25, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0 },
-#ifdef LINE30
- { M_PC98_80x30, V_INFO_COLOR, 80, 30, 8, 16, 4, 1,
- TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, 0 },
-#endif
- { EOT },
-};
-
-static int init_done = FALSE;
-
-/* local functions */
-static int map_gen_mode_num(int type, int color, int mode);
-static int probe_adapters(void);
-static void dump_buffer(u_char *buf, size_t len);
-
-#define prologue(adp, flag, err) \
- if (!init_done || !((adp)->va_flags & (flag))) \
- return (err)
-
-/* a backdoor for the console driver */
-static int
-gdc_configure(int flags)
-{
- probe_adapters();
- biosadapter[0].va_flags |= V_ADP_INITIALIZED;
- if (!config_done(&biosadapter[0])) {
- if (vid_register(&biosadapter[0]) < 0)
- return 1;
- biosadapter[0].va_flags |= V_ADP_REGISTERED;
- }
-
- return 1;
-}
-
-/* local subroutines */
-
-/* map a generic video mode to a known mode number */
-static int
-map_gen_mode_num(int type, int color, int mode)
-{
- static struct {
- int from;
- int to;
- } mode_map[] = {
- { M_TEXT_80x25, M_PC98_80x25, },
-#ifdef LINE30
- { M_TEXT_80x30, M_PC98_80x30, },
-#endif
- };
- int i;
-
- for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
- if (mode_map[i].from == mode)
- return mode_map[i].to;
- }
- return mode;
-}
-
-/* probe video adapters and return the number of detected adapters */
-static int
-probe_adapters(void)
-{
- video_info_t info;
-
- /* do this test only once */
- if (init_done)
- return 1;
- init_done = TRUE;
-
- biosadapter[0] = adapter_init_value[0];
- biosadapter[0].va_flags |= V_ADP_PROBED;
- biosadapter[0].va_mode =
- biosadapter[0].va_initial_mode = biosadapter[0].va_initial_bios_mode;
-
- master_gdc_wait_vsync();
- master_gdc_cmd(_GDC_START); /* text ON */
- gdc_wait_vsync();
- gdc_cmd(_GDC_STOP); /* graphics OFF */
-
- gdc_get_info(&biosadapter[0], biosadapter[0].va_initial_mode, &info);
- biosadapter[0].va_mode_flags = info.vi_flags;
- biosadapter[0].va_window = BIOS_PADDRTOVADDR(info.vi_window);
- biosadapter[0].va_window_size = info.vi_window_size;
- biosadapter[0].va_window_gran = info.vi_window_gran;
- biosadapter[0].va_buffer = 0;
- biosadapter[0].va_buffer_size = 0;
-
- return 1;
-}
-
-static void master_gdc_cmd(unsigned int cmd)
-{
- while ( (inb(IO_GDC1) & 2) != 0);
- outb(IO_GDC1+2, cmd);
-}
-
-static void master_gdc_prm(unsigned int pmtr)
-{
- while ( (inb(IO_GDC1) & 2) != 0);
- outb(IO_GDC1, pmtr);
-}
-
-static void master_gdc_word_prm(unsigned int wpmtr)
-{
- master_gdc_prm(wpmtr & 0x00ff);
- master_gdc_prm((wpmtr >> 8) & 0x00ff);
-}
-
-static void master_gdc_fifo_empty(void)
-{
- while ( (inb(IO_GDC1) & 4) == 0);
-}
-
-static void master_gdc_wait_vsync(void)
-{
- while ( (inb(IO_GDC1) & 0x20) != 0);
- while ( (inb(IO_GDC1) & 0x20) == 0);
-}
-
-static void gdc_cmd(unsigned int cmd)
-{
- while ( (inb(IO_GDC2) & 2) != 0);
- outb( IO_GDC2+2, cmd);
-}
-
-static void gdc_prm(unsigned int pmtr)
-{
- while ( (inb(IO_GDC2) & 2) != 0);
- outb( IO_GDC2, pmtr);
-}
-
-static void gdc_word_prm(unsigned int wpmtr)
-{
- gdc_prm(wpmtr & 0x00ff);
- gdc_prm((wpmtr >> 8) & 0x00ff);
-}
-
-static void gdc_fifo_empty(void)
-{
- while ( (inb(IO_GDC2) & 0x04) == 0);
-}
-
-static void gdc_wait_vsync(void)
-{
- while ( (inb(IO_GDC2) & 0x20) != 0);
- while ( (inb(IO_GDC2) & 0x20) == 0);
-}
-
-static int check_gdc_clock(void)
-{
- if ((inb(IO_SYSPORT) & 0x80) == 0){
- return _5MHZ;
- } else {
- return _2_5MHZ;
- }
-}
-
-static void initialize_gdc(unsigned int mode)
-{
- /* start 30line initialize */
- int m_mode,s_mode,gdc_clock;
- gdc_clock = check_gdc_clock();
-
- if (mode == T25_G400){
- m_mode = _25L;
- }else{
- m_mode = _30L;
- }
-
- s_mode = 2*mode+gdc_clock;
-
- gdc_INFO = m_mode;
-
- master_gdc_cmd(_GDC_RESET);
- master_gdc_cmd(_GDC_MASTER);
- gdc_cmd(_GDC_RESET);
- gdc_cmd(_GDC_SLAVE);
-
- /* GDC Master */
- master_gdc_cmd(_GDC_SYNC);
- master_gdc_prm(0x00); /* flush less */ /* text & graph */
- master_gdc_prm(master_param[m_mode][GDC_CR]);
- master_gdc_word_prm(((master_param[m_mode][GDC_HFP] << 10)
- + (master_param[m_mode][GDC_VS] << 5)
- + master_param[m_mode][GDC_HS]));
- master_gdc_prm(master_param[m_mode][GDC_HBP]);
- master_gdc_prm(master_param[m_mode][GDC_VFP]);
- master_gdc_word_prm(((master_param[m_mode][GDC_VBP] << 10)
- + (master_param[m_mode][GDC_LF])));
- master_gdc_fifo_empty();
- master_gdc_cmd(_GDC_PITCH);
- master_gdc_prm(MasterPCH);
- master_gdc_fifo_empty();
-
- /* GDC slave */
- gdc_cmd(_GDC_SYNC);
- gdc_prm(0x06);
- gdc_prm(slave_param[s_mode][GDC_CR]);
- gdc_word_prm((slave_param[s_mode][GDC_HFP] << 10)
- + (slave_param[s_mode][GDC_VS] << 5)
- + (slave_param[s_mode][GDC_HS]));
- gdc_prm(slave_param[s_mode][GDC_HBP]);
- gdc_prm(slave_param[s_mode][GDC_VFP]);
- gdc_word_prm((slave_param[s_mode][GDC_VBP] << 10)
- + (slave_param[s_mode][GDC_LF]));
- gdc_fifo_empty();
- gdc_cmd(_GDC_PITCH);
- gdc_prm(SlavePCH[gdc_clock]);
- gdc_fifo_empty();
-
- /* set Master GDC scroll param */
- master_gdc_wait_vsync();
- master_gdc_wait_vsync();
- master_gdc_wait_vsync();
- master_gdc_cmd(_GDC_SCROLL);
- master_gdc_word_prm(0);
- master_gdc_word_prm((master_param[m_mode][GDC_LF] << 4) | 0x0000);
- master_gdc_fifo_empty();
-
- /* set Slave GDC scroll param */
- gdc_wait_vsync();
- gdc_cmd(_GDC_SCROLL);
- gdc_word_prm(0);
- if (gdc_clock == _5MHZ){
- gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
- }else{
- gdc_word_prm(SlaveScrlLF[mode] << 4);
- }
- gdc_fifo_empty();
-
- gdc_word_prm(0);
- if (gdc_clock == _5MHZ){
- gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
- }else{
- gdc_word_prm(SlaveScrlLF[mode] << 4);
- }
- gdc_fifo_empty();
-
- /* sync start */
- gdc_cmd(_GDC_STOP);
-
- gdc_wait_vsync();
- gdc_wait_vsync();
- gdc_wait_vsync();
-
- master_gdc_cmd(_GDC_START);
-}
-
-/* entry points */
-
-static int
-gdc_nop(void)
-{
- return 0;
-}
-
-static int
-gdc_probe(int unit, video_adapter_t **adpp, void *arg, int flags)
-{
- probe_adapters();
- if (unit >= 1)
- return ENXIO;
-
- *adpp = &biosadapter[unit];
-
- return 0;
-}
-
-static int
-gdc_init(int unit, video_adapter_t *adp, int flags)
-{
- if ((unit >= 1) || (adp == NULL) || !probe_done(adp))
- return ENXIO;
-
- if (!init_done(adp)) {
- /* nothing to do really... */
- adp->va_flags |= V_ADP_INITIALIZED;
- }
-
- if (!config_done(adp)) {
- if (vid_register(adp) < 0)
- return ENXIO;
- adp->va_flags |= V_ADP_REGISTERED;
- }
-
- return 0;
-}
-
-/*
- * get_info():
- * Return the video_info structure of the requested video mode.
- */
-static int
-gdc_get_info(video_adapter_t *adp, int mode, video_info_t *info)
-{
- int i;
-
- if (!init_done)
- return 1;
-
- mode = map_gen_mode_num(adp->va_type, adp->va_flags & V_ADP_COLOR, mode);
- for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
- if (bios_vmode[i].vi_mode == NA)
- continue;
- if (mode == bios_vmode[i].vi_mode) {
- *info = bios_vmode[i];
- return 0;
- }
- }
- return 1;
-}
-
-/*
- * query_mode():
- * Find a video mode matching the requested parameters.
- * Fields filled with 0 are considered "don't care" fields and
- * match any modes.
- */
-static int
-gdc_query_mode(video_adapter_t *adp, video_info_t *info)
-{
- video_info_t buf;
- int i;
-
- if (!init_done)
- return -1;
-
- for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
- if (bios_vmode[i].vi_mode == NA)
- continue;
-
- if ((info->vi_width != 0)
- && (info->vi_width != bios_vmode[i].vi_width))
- continue;
- if ((info->vi_height != 0)
- && (info->vi_height != bios_vmode[i].vi_height))
- continue;
- if ((info->vi_cwidth != 0)
- && (info->vi_cwidth != bios_vmode[i].vi_cwidth))
- continue;
- if ((info->vi_cheight != 0)
- && (info->vi_cheight != bios_vmode[i].vi_cheight))
- continue;
- if ((info->vi_depth != 0)
- && (info->vi_depth != bios_vmode[i].vi_depth))
- continue;
- if ((info->vi_planes != 0)
- && (info->vi_planes != bios_vmode[i].vi_planes))
- continue;
- /* XXX: should check pixel format, memory model */
- if ((info->vi_flags != 0)
- && (info->vi_flags != bios_vmode[i].vi_flags))
- continue;
-
- /* verify if this mode is supported on this adapter */
- if (gdc_get_info(adp, bios_vmode[i].vi_mode, &buf))
- continue;
- return bios_vmode[i].vi_mode;
- }
- return -1;
-}
-
-/*
- * set_mode():
- * Change the video mode.
- */
-static int
-gdc_set_mode(video_adapter_t *adp, int mode)
-{
- video_info_t info;
-
- prologue(adp, V_ADP_MODECHANGE, 1);
-
- mode = map_gen_mode_num(adp->va_type,
- adp->va_flags & V_ADP_COLOR, mode);
- if (gdc_get_info(adp, mode, &info))
- return 1;
-
-#ifdef LINE30
- switch (scp->mode) {
- case M_PC98_80x25: /* VGA TEXT MODES */
- initialize_gdc(T25_G400);
- break;
- case M_PC98_80x30:
- initialize_gdc(T30_G400);
- break;
- default:
- break;
- }
-#endif
-
- adp->va_mode = mode;
- adp->va_mode_flags = info.vi_flags;
- adp->va_flags &= ~V_ADP_COLOR;
- adp->va_flags |=
- (info.vi_flags & V_INFO_COLOR) ? V_ADP_COLOR : 0;
-#if 0
- adp->va_crtc_addr =
- (adp->va_flags & V_ADP_COLOR) ? COLOR_CRTC : MONO_CRTC;
-#endif
- adp->va_window = BIOS_PADDRTOVADDR(info.vi_window);
- adp->va_window_size = info.vi_window_size;
- adp->va_window_gran = info.vi_window_gran;
- if (info.vi_buffer_size == 0) {
- adp->va_buffer = 0;
- adp->va_buffer_size = 0;
- } else {
- adp->va_buffer = BIOS_PADDRTOVADDR(info.vi_buffer);
- adp->va_buffer_size = info.vi_buffer_size;
- }
-
- /* move hardware cursor out of the way */
- (*vidsw[adp->va_index]->set_hw_cursor)(adp, -1, -1);
-
- return 0;
-}
-
-/*
- * set_border():
- * Change the border color.
- */
-static int
-gdc_set_border(video_adapter_t *adp, int color)
-{
- outb(0x6c, color << 4);
- return 0;
-}
-
-/*
- * save_state():
- * Read video card register values.
- */
-static int
-gdc_save_state(video_adapter_t *adp, void *p, size_t size)
-{
- return 1;
-}
-
-/*
- * load_state():
- * Set video card registers at once.
- */
-static int
-gdc_load_state(video_adapter_t *adp, void *p)
-{
- return 1;
-}
-
-/*
- * read_hw_cursor():
- * Read the position of the hardware text cursor.
- */
-static int
-gdc_read_hw_cursor(video_adapter_t *adp, int *col, int *row)
-{
- video_info_t info;
- u_int16_t off;
- int s;
-
- if (!init_done)
- return 1;
-
- (*vidsw[adp->va_index]->get_info)(adp, adp->va_mode, &info);
- if (info.vi_flags & V_INFO_GRAPHICS)
- return 1;
-
- s = spltty();
- master_gdc_cmd(0xe0); /* _GDC_CSRR */
- while((inb(TEXT_GDC + 0) & 0x1) == 0) {} /* GDC wait */
- off = inb(TEXT_GDC + 2); /* EADl */
- off |= (inb(TEXT_GDC + 2) << 8); /* EADh */
- inb(TEXT_GDC + 2); /* dummy */
- inb(TEXT_GDC + 2); /* dummy */
- inb(TEXT_GDC + 2); /* dummy */
- splx(s);
-
- if (off >= ROW*COL)
- off = 0;
- *row = off / info.vi_width;
- *col = off % info.vi_width;
-
- return 0;
-}
-
-/*
- * set_hw_cursor():
- * Move the hardware text cursor. If col and row are both -1,
- * the cursor won't be shown.
- */
-static int
-gdc_set_hw_cursor(video_adapter_t *adp, int col, int row)
-{
- video_info_t info;
- u_int16_t off;
- int s;
-
- if (!init_done)
- return 1;
-
- if ((col == -1) && (row == -1)) {
- off = -1;
- } else {
- (*vidsw[adp->va_index]->get_info)(adp, adp->va_mode, &info);
- if (info.vi_flags & V_INFO_GRAPHICS)
- return 1;
- off = row*info.vi_width + col;
- }
-
- s = spltty();
- master_gdc_cmd(0x49); /* _GDC_CSRW */
- master_gdc_word_prm(off);
- splx(s);
-
- return 0;
-}
-
-/*
- * set_hw_cursor_shape():
- * Change the shape of the hardware text cursor. If the height is zero
- * or negative, the cursor won't be shown.
- */
-static int
-gdc_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
- int celsize, int blink)
-{
- int start;
- int end;
- int s;
-
- start = celsize - (base + height);
- end = celsize - base - 1;
- /*
- * muPD7220 GDC has anomaly that if end == celsize - 1 then start
- * must be 0, otherwise the cursor won't be correctly shown
- * in the first row in the screen. We shall set end to celsize - 2;
- * if end == celsize -1 && start > 0. XXX
- */
- if ((end == celsize - 1) && (start > 0))
- --end;
-
- s = spltty();
- master_gdc_cmd(0x4b); /* _GDC_CSRFORM */
- master_gdc_prm(((height > 0) ? 0x80 : 0) /* cursor on/off */
- | (celsize - 1) & 0x1f); /* cel size */
- master_gdc_word_prm(((end & 0x1f) << 11) /* end line */
- | (12 << 6) /* blink rate */
- | (blink ? 0x20 : 0) /* blink on/off */
- | (start & 0x1f)); /* start line */
- splx(s);
-
- return 1;
-}
-
-static void
-dump_buffer(u_char *buf, size_t len)
-{
- int i;
-
- for(i = 0; i < len;) {
- printf("%02x ", buf[i]);
- if ((++i % 16) == 0)
- printf("\n");
- }
-}
-
-/*
- * mmap():
- * Mmap frame buffer.
- */
-static int
-gdc_mmap(video_adapter_t *adp, vm_offset_t offset)
-{
- if (offset > 0x48000 - PAGE_SIZE)
- return -1;
- return i386_btop((VIDEO_BUF_BASE + offset));
-}
-
-/*
- * diag():
- * Print some information about the video adapter and video modes,
- * with requested level of details.
- */
-static int
-gdc_diag(video_adapter_t *adp, int level)
-{
- video_info_t info;
- int i;
-
- if (!init_done)
- return 1;
-
- fb_dump_adp_info(DRIVER_NAME, adp, level);
-
-#if FB_DEBUG > 1
- for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) {
- if (bios_vmode[i].vi_mode == NA)
- continue;
- if (get_mode_param(bios_vmode[i].vi_mode) == NULL)
- continue;
- fb_dump_mode_info(DRIVER_NAME, adp, &bios_vmode[i], level);
- }
-#endif
-
- return 0;
-}
-
-static int
-gdc_err(video_adapter_t *adp, ...)
-{
- return 0;
-}
-
-#endif /* NGDC > 0 */
diff --git a/sys/pc98/pc98/pc98kbd.c b/sys/pc98/pc98/pc98kbd.c
deleted file mode 100644
index 668ae9d8ae43..000000000000
--- a/sys/pc98/pc98/pc98kbd.c
+++ /dev/null
@@ -1,1009 +0,0 @@
-/*
- * Copyright (c) 1999 FreeBSD(98) port team.
- * 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 as
- * the first lines of this file unmodified.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id: pc98kbd.c,v 1.3 1999/01/19 12:41:26 kato Exp $
- */
-
-#include "pckbd.h"
-#include "opt_kbd.h"
-#include "opt_devfs.h"
-
-#if NPCKBD > 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/conf.h>
-#include <sys/proc.h>
-#include <sys/tty.h>
-#include <sys/fcntl.h>
-#include <sys/bus.h>
-#include <sys/malloc.h>
-
-#include <machine/resource.h>
-
-#include <dev/kbd/kbdreg.h>
-
-#include <pc98/pc98/pc98.h>
-#include <pc98/pc98/pc98_machdep.h>
-
-#ifdef __i386__
-#include <i386/isa/isa_device.h>
-#endif
-
-#define DRIVER_NAME "pckbd"
-
-/* device configuration flags */
-#define KB_CONF_FAIL_IF_NO_KBD (1 << 0) /* don't install if no kbd is found */
-
-/* some macros */
-#define PC98KBD_UNIT(dev) minor(dev)
-#define PC98KBD_MKMINOR(unit) (unit)
-
-/* cdev driver declaration */
-
-typedef struct pckbd_softc {
- short flags;
-#define PC98KBD_ATTACHED (1 << 0)
- keyboard_t *kbd;
-#ifdef KBD_INSTALL_CDEV
- genkbd_softc_t gensc;
-#endif
-} pckbd_softc_t;
-
-#define PC98KBD_SOFTC(unit) pckbd_softc[(unit)]
-
-static pckbd_softc_t *pckbd_softc[NPCKBD];
-
-static int pckbdprobe(struct isa_device *dev);
-static int pckbdattach(struct isa_device *dev);
-
-static ointhand2_t pckbd_isa_intr;
-
-/* driver declaration for isa_devtab_tty[] */
-struct isa_driver pckbddriver = {
- pckbdprobe,
- pckbdattach,
- DRIVER_NAME,
- 0,
-};
-
-static int pckbd_probe_unit(int unit, pckbd_softc_t *sc,
- int port, int irq, int flags);
-static int pckbd_attach_unit(int unit, pckbd_softc_t *sc);
-static timeout_t pckbd_timeout;
-
-#ifdef KBD_INSTALL_CDEV
-
-static d_open_t pckbdopen;
-static d_close_t pckbdclose;
-static d_read_t pckbdread;
-static d_ioctl_t pckbdioctl;
-static d_poll_t pckbdpoll;
-
-static struct cdevsw pckbd_cdevsw = {
- pckbdopen, pckbdclose, pckbdread, nowrite,
- pckbdioctl, nostop, nullreset, nodevtotty,
- pckbdpoll, nommap, NULL, DRIVER_NAME,
- NULL, -1,
-};
-
-#endif /* KBD_INSTALL_CDEV */
-
-static int
-pckbdprobe(struct isa_device *dev)
-{
- pckbd_softc_t *sc;
- int error;
-
- if (dev->id_unit >= sizeof(pckbd_softc)/sizeof(pckbd_softc[0]))
- return 0;
- sc = pckbd_softc[dev->id_unit];
- if (sc == NULL) {
- sc = pckbd_softc[dev->id_unit]
- = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
- if (sc == NULL)
- return 0;
- bzero(sc, sizeof(*sc));
- }
-
- /* try to find a keyboard */
- error = pckbd_probe_unit(dev->id_unit, sc, dev->id_iobase,
- dev->id_irq, dev->id_flags);
- if (error)
- return 0;
-
- /* declare our interrupt handler */
- dev->id_ointr = pckbd_isa_intr;
-
- return IO_KBDSIZE;
-}
-
-static int
-pckbdattach(struct isa_device *dev)
-{
- pckbd_softc_t *sc;
-
- if (dev->id_unit >= sizeof(pckbd_softc)/sizeof(pckbd_softc[0]))
- return 0;
- sc = pckbd_softc[dev->id_unit];
- if (sc == NULL)
- return 0;
-
- return ((pckbd_attach_unit(dev->id_unit, sc)) ? 0 : 1);
-}
-
-static void
-pckbd_isa_intr(int unit)
-{
- keyboard_t *kbd;
-
- kbd = pckbd_softc[unit]->kbd;
- (*kbdsw[kbd->kb_index]->intr)(kbd);
-}
-
-static int
-pckbd_probe_unit(int unit, pckbd_softc_t *sc, int port, int irq, int flags)
-{
- keyboard_switch_t *sw;
- int args[2];
-
- if (sc->flags & PC98KBD_ATTACHED)
- return 0;
-
- sw = kbd_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
-
- args[0] = port;
- args[1] = irq;
- return (*sw->probe)(unit, &sc->kbd, args, flags);
-}
-
-static int
-pckbd_attach_unit(int unit, pckbd_softc_t *sc)
-{
- keyboard_switch_t *sw;
- int error;
-
- if (sc->flags & PC98KBD_ATTACHED)
- return 0;
-
- sw = kbd_get_switch(DRIVER_NAME);
- if (sw == NULL)
- return ENXIO;
-
- /* reset, initialize and enable the device */
- error = (*sw->init)(sc->kbd);
- if (error)
- return ENXIO;
- (*sw->enable)(sc->kbd);
-
-#ifdef KBD_INSTALL_CDEV
- /* attach a virtual keyboard cdev */
- error = kbd_attach(makedev(0, PC98KBD_MKMINOR(unit)), sc->kbd,
- &pckbd_cdevsw);
- if (error)
- return error;
-#endif /* KBD_INSTALL_CDEV */
-
- /*
- * This is a kludge to compensate for lost keyboard interrupts.
- * A similar code used to be in syscons. See below. XXX
- */
- pckbd_timeout(sc->kbd);
-
- if (bootverbose)
- (*sw->diag)(sc->kbd, bootverbose);
-
- sc->flags |= PC98KBD_ATTACHED;
- return 0;
-}
-
-static void
-pckbd_timeout(void *arg)
-{
- keyboard_t *kbd;
- int s;
-
- /* The following comments are extracted from syscons.c (1.287) */
- /*
- * With release 2.1 of the Xaccel server, the keyboard is left
- * hanging pretty often. Apparently an interrupt from the
- * keyboard is lost, and I don't know why (yet).
- * This ugly hack calls scintr if input is ready for the keyboard
- * and conveniently hides the problem. XXX
- */
- /*
- * Try removing anything stuck in the keyboard controller; whether
- * it's a keyboard scan code or mouse data. `scintr()' doesn't
- * read the mouse data directly, but `kbdio' routines will, as a
- * side effect.
- */
- s = spltty();
- kbd = (keyboard_t *)arg;
- if ((*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) {
- /*
- * We have seen the lock flag is not set. Let's reset
- * the flag early, otherwise the LED update routine fails
- * which may want the lock during the interrupt routine.
- */
- (*kbdsw[kbd->kb_index]->lock)(kbd, FALSE);
- if ((*kbdsw[kbd->kb_index]->check_char)(kbd))
- (*kbdsw[kbd->kb_index]->intr)(kbd);
- }
- splx(s);
- timeout(pckbd_timeout, arg, hz/10);
-}
-
-/* cdev driver functions */
-
-#ifdef KBD_INSTALL_CDEV
-
-static int
-pckbdopen(dev_t dev, int flag, int mode, struct proc *p)
-{
- pckbd_softc_t *sc;
- int unit;
-
- unit = PC98KBD_UNIT(dev);
- if ((unit >= NPCKBD) || ((sc = PC98KBD_SOFTC(unit)) == NULL))
- return ENXIO;
- if (mode & (FWRITE | O_CREAT | O_APPEND | O_TRUNC))
- return ENODEV;
-
- /* FIXME: set the initial input mode (K_XLATE?) and lock state? */
- return genkbdopen(&sc->gensc, sc->kbd, flag, mode, p);
-}
-
-static int
-pckbdclose(dev_t dev, int flag, int mode, struct proc *p)
-{
- pckbd_softc_t *sc;
-
- sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
- return genkbdclose(&sc->gensc, sc->kbd, flag, mode, p);
-}
-
-static int
-pckbdread(dev_t dev, struct uio *uio, int flag)
-{
- pckbd_softc_t *sc;
-
- sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
- return genkbdread(&sc->gensc, sc->kbd, uio, flag);
-}
-
-static int
-pckbdioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
-{
- pckbd_softc_t *sc;
-
- sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
- return genkbdioctl(&sc->gensc, sc->kbd, cmd, arg, flag, p);
-}
-
-static int
-pckbdpoll(dev_t dev, int event, struct proc *p)
-{
- pckbd_softc_t *sc;
-
- sc = PC98KBD_SOFTC(PC98KBD_UNIT(dev));
- return genkbdpoll(&sc->gensc, sc->kbd, event, p);
-}
-
-#endif /* KBD_INSTALL_CDEV */
-
-/* LOW-LEVEL */
-
-#include <machine/limits.h>
-#include <machine/console.h>
-#include <machine/clock.h>
-
-#define PC98KBD_DEFAULT 0
-
-typedef caddr_t KBDC;
-
-typedef struct pckbd_state {
- KBDC kbdc; /* keyboard controller */
- int ks_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */
- int ks_flags; /* flags */
-#define COMPOSE (1 << 0)
- int ks_state; /* shift/lock key state */
- int ks_accents; /* accent key index (> 0) */
- u_int ks_composed_char; /* composed char code (> 0) */
-} pckbd_state_t;
-
-/* keyboard driver declaration */
-static int pckbd_configure(int flags);
-static kbd_probe_t pckbd_probe;
-static kbd_init_t pckbd_init;
-static kbd_term_t pckbd_term;
-static kbd_intr_t pckbd_intr;
-static kbd_test_if_t pckbd_test_if;
-static kbd_enable_t pckbd_enable;
-static kbd_disable_t pckbd_disable;
-static kbd_read_t pckbd_read;
-static kbd_check_t pckbd_check;
-static kbd_read_char_t pckbd_read_char;
-static kbd_check_char_t pckbd_check_char;
-static kbd_ioctl_t pckbd_ioctl;
-static kbd_lock_t pckbd_lock;
-static kbd_clear_state_t pckbd_clear_state;
-static kbd_get_state_t pckbd_get_state;
-static kbd_set_state_t pckbd_set_state;
-
-keyboard_switch_t pckbdsw = {
- pckbd_probe,
- pckbd_init,
- pckbd_term,
- pckbd_intr,
- pckbd_test_if,
- pckbd_enable,
- pckbd_disable,
- pckbd_read,
- pckbd_check,
- pckbd_read_char,
- pckbd_check_char,
- pckbd_ioctl,
- pckbd_lock,
- pckbd_clear_state,
- pckbd_get_state,
- pckbd_set_state,
- genkbd_get_fkeystr,
- genkbd_diag,
-};
-
-KEYBOARD_DRIVER(pckbd, pckbdsw, pckbd_configure);
-
-struct kbdc_softc {
- int port; /* base port address */
- int lock; /* FIXME: XXX not quite a semaphore... */
-};
-
-/* local functions */
-static int probe_keyboard(KBDC kbdc, int flags);
-static int init_keyboard(KBDC kbdc, int *type, int flags);
-static KBDC kbdc_open(int port);
-static int kbdc_lock(KBDC kbdc, int lock);
-static int kbdc_data_ready(KBDC kbdc);
-static int read_kbd_data(KBDC kbdc);
-static int read_kbd_data_no_wait(KBDC kbdc);
-static int wait_for_kbd_data(struct kbdc_softc *kbdc);
-
-/* local variables */
-
-/* the initial key map, accent map and fkey strings */
-#include <dev/kbd/kbdtables.h>
-
-/* structures for the default keyboard */
-static keyboard_t default_kbd;
-static pckbd_state_t default_kbd_state;
-static keymap_t default_keymap;
-static accentmap_t default_accentmap;
-static fkeytab_t default_fkeytab[NUM_FKEYS];
-
-/*
- * The back door to the keyboard driver!
- * This function is called by the console driver, via the kbdio module,
- * to tickle keyboard drivers when the low-level console is being initialized.
- * Almost nothing in the kernel has been initialied yet. Try to probe
- * keyboards if possible.
- * NOTE: because of the way the low-level conole is initialized, this routine
- * may be called more than once!!
- */
-static int
-pckbd_configure(int flags)
-{
- keyboard_t *kbd;
- KBDC kbdc;
- int arg[2];
- struct isa_device *dev;
-
- /* XXX: a kludge to obtain the device configuration flags */
- dev = find_isadev(isa_devtab_tty, &pckbddriver, 0);
- if (dev != NULL)
- flags |= dev->id_flags;
-
- /* probe the default keyboard */
- arg[0] = -1;
- arg[1] = -1;
- if (pckbd_probe(PC98KBD_DEFAULT, &kbd, arg, flags))
- return 0;
-
- /* initialize it */
- kbdc = ((pckbd_state_t *)kbd->kb_data)->kbdc;
- if (!(flags & KB_CONF_PROBE_ONLY) && !KBD_IS_PROBED(kbd)) {
- if (KBD_HAS_DEVICE(kbd)
- && init_keyboard(kbdc, &kbd->kb_type, flags)
- && (flags & KB_CONF_FAIL_IF_NO_KBD))
- return 0;
- KBD_INIT_DONE(kbd);
- }
-
- /* and register */
- if (!KBD_IS_CONFIGURED(kbd)) {
- if (kbd_register(kbd) < 0)
- return 0;
- KBD_CONFIG_DONE(kbd);
- }
-
- return 1; /* return the number of found keyboards */
-}
-
-/* low-level functions */
-
-/* initialize the keyboard_t structure and try to detect a keyboard */
-static int
-pckbd_probe(int unit, keyboard_t **kbdp, void *arg, int flags)
-{
- keyboard_t *kbd;
- pckbd_state_t *state;
- keymap_t *keymap;
- accentmap_t *accmap;
- fkeytab_t *fkeymap;
- int fkeymap_size;
- KBDC kbdc;
- int *data = (int *)arg;
-
- if (unit != PC98KBD_DEFAULT)
- return ENXIO;
-
- *kbdp = kbd = &default_kbd;
- if (KBD_IS_PROBED(kbd))
- return 0;
- state = &default_kbd_state;
- keymap = &default_keymap;
- accmap = &default_accentmap;
- fkeymap = default_fkeytab;
- fkeymap_size = sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
-
- state->kbdc = kbdc = kbdc_open(data[0]);
- if (kbdc == NULL)
- return ENXIO;
- kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, unit, flags, data[0],
- IO_KBDSIZE);
- bcopy(&key_map, keymap, sizeof(key_map));
- bcopy(&accent_map, accmap, sizeof(accent_map));
- bcopy(fkey_tab, fkeymap,
- imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
- kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
- kbd->kb_data = (void *)state;
-
- if (probe_keyboard(kbdc, flags)) {
- if (flags & KB_CONF_FAIL_IF_NO_KBD)
- return ENXIO;
- } else {
- KBD_FOUND_DEVICE(kbd);
- }
- pckbd_clear_state(kbd);
- state->ks_mode = K_XLATE;
-
- KBD_PROBE_DONE(kbd);
- return 0;
-}
-
-/* reset and initialize the device */
-static int
-pckbd_init(keyboard_t *kbd)
-{
- KBDC kbdc;
-
- if ((kbd == NULL) || !KBD_IS_PROBED(kbd))
- return ENXIO; /* shouldn't happen */
- kbdc = ((pckbd_state_t *)kbd->kb_data)->kbdc;
- if (kbdc == NULL)
- return ENXIO; /* shouldn't happen */
-
- if (!KBD_IS_INITIALIZED(kbd)) {
- if (KBD_HAS_DEVICE(kbd)
- && init_keyboard(kbdc, &kbd->kb_type, kbd->kb_config)
- && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD))
- return ENXIO;
- pckbd_ioctl(kbd, KDSETLED,
- (caddr_t)&((pckbd_state_t *)(kbd->kb_data))->ks_state);
- KBD_INIT_DONE(kbd);
- }
- if (!KBD_IS_CONFIGURED(kbd)) {
- if (kbd_register(kbd) < 0)
- return ENXIO;
- KBD_CONFIG_DONE(kbd);
- }
-
- return 0;
-}
-
-/* finish using this keyboard */
-static int
-pckbd_term(keyboard_t *kbd)
-{
- kbd_unregister(kbd);
- return 0;
-}
-
-/* keyboard interrupt routine */
-static int
-pckbd_intr(keyboard_t *kbd)
-{
- int c;
-
- if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
- /* let the callback function to process the input */
- (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
- kbd->kb_callback.kc_arg);
- } else {
- /* read and discard the input; no one is waiting for input */
- do {
- c = pckbd_read_char(kbd, FALSE);
- } while (c != NOKEY);
- }
- return 0;
-}
-
-/* test the interface to the device */
-static int
-pckbd_test_if(keyboard_t *kbd)
-{
- return 0;
-}
-
-/*
- * Enable the access to the device; until this function is called,
- * the client cannot read from the keyboard.
- */
-static int
-pckbd_enable(keyboard_t *kbd)
-{
- int s;
-
- s = spltty();
- KBD_ACTIVATE(kbd);
- splx(s);
- return 0;
-}
-
-/* disallow the access to the device */
-static int
-pckbd_disable(keyboard_t *kbd)
-{
- int s;
-
- s = spltty();
- KBD_DEACTIVATE(kbd);
- splx(s);
- return 0;
-}
-
-/* read one byte from the keyboard if it's allowed */
-static int
-pckbd_read(keyboard_t *kbd, int wait)
-{
- int c;
-
- if (wait)
- c = read_kbd_data(((pckbd_state_t *)kbd->kb_data)->kbdc);
- else
- c = read_kbd_data_no_wait(((pckbd_state_t *)kbd->kb_data)->kbdc);
- return (KBD_IS_ACTIVE(kbd) ? c : -1);
-}
-
-/* check if data is waiting */
-static int
-pckbd_check(keyboard_t *kbd)
-{
- if (!KBD_IS_ACTIVE(kbd))
- return FALSE;
- return kbdc_data_ready(((pckbd_state_t *)kbd->kb_data)->kbdc);
-}
-
-/* read char from the keyboard */
-static u_int
-pckbd_read_char(keyboard_t *kbd, int wait)
-{
- pckbd_state_t *state;
- u_int action;
- int scancode;
- int keycode;
-
- state = (pckbd_state_t *)kbd->kb_data;
-next_code:
- /* do we have a composed char to return? */
- if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
- action = state->ks_composed_char;
- state->ks_composed_char = 0;
- if (action > UCHAR_MAX)
- return ERRKEY;
- return action;
- }
-
- /* see if there is something in the keyboard port */
- if (wait) {
- do {
- scancode = read_kbd_data(state->kbdc);
- } while (scancode == -1);
- } else {
- scancode = read_kbd_data_no_wait(state->kbdc);
- if (scancode == -1)
- return NOKEY;
- }
-
- /* return the byte as is for the K_RAW mode */
- if (state->ks_mode == K_RAW)
- return scancode;
-
- /* translate the scan code into a keycode */
- keycode = scancode & 0x7F;
- switch(scancode) {
- case 0xF3: /* GRPH (compose key) released */
- if (state->ks_flags & COMPOSE) {
- state->ks_flags &= ~COMPOSE;
- if (state->ks_composed_char > UCHAR_MAX)
- state->ks_composed_char = 0;
- }
- break;
- case 0x73: /* GRPH (compose key) pressed */
- if (!(state->ks_flags & COMPOSE)) {
- state->ks_flags |= COMPOSE;
- state->ks_composed_char = 0;
- }
- break;
- }
-
- /* return the key code in the K_CODE mode */
- if (state->ks_mode == K_CODE)
- return (keycode | (scancode & 0x80));
-
- /* compose a character code */
- if (state->ks_flags & COMPOSE) {
- switch (scancode) {
- /* key pressed, process it */
- case 0x42: case 0x43: case 0x44: /* keypad 7,8,9 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += scancode - 0x3B;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x46: case 0x47: case 0x48: /* keypad 4,5,6 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += scancode - 0x42;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x4A: case 0x4B: case 0x4C: /* keypad 1,2,3 */
- state->ks_composed_char *= 10;
- state->ks_composed_char += scancode - 0x49;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
- case 0x4E: /* keypad 0 */
- state->ks_composed_char *= 10;
- if (state->ks_composed_char > UCHAR_MAX)
- return ERRKEY;
- goto next_code;
-
- /* key released, no interest here */
- case 0xC2: case 0xC3: case 0xC4: /* keypad 7,8,9 */
- case 0xC6: case 0xC7: case 0xC8: /* keypad 4,5,6 */
- case 0xCA: case 0xCB: case 0xCC: /* keypad 1,2,3 */
- case 0xCE: /* keypad 0 */
- goto next_code;
-
- case 0x73: /* GRPH key */
- break;
-
- default:
- if (state->ks_composed_char > 0) {
- state->ks_flags &= ~COMPOSE;
- state->ks_composed_char = 0;
- return ERRKEY;
- }
- break;
- }
- }
-
- /* keycode to key action */
- action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
- &state->ks_state, &state->ks_accents);
- if (action == NOKEY)
- goto next_code;
- else
- return action;
-}
-
-/* check if char is waiting */
-static int
-pckbd_check_char(keyboard_t *kbd)
-{
- pckbd_state_t *state;
-
- if (!KBD_IS_ACTIVE(kbd))
- return FALSE;
- state = (pckbd_state_t *)kbd->kb_data;
- if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
- return TRUE;
- return kbdc_data_ready(state->kbdc);
-}
-
-/* some useful control functions */
-static int
-pckbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
-{
- pckbd_state_t *state = kbd->kb_data;
- int s;
- int i;
-
- s = spltty();
- switch (cmd) {
-
- case KDGKBMODE: /* get keyboard mode */
- *(int *)arg = state->ks_mode;
- break;
- case KDSKBMODE: /* set keyboard mode */
- switch (*(int *)arg) {
- case K_XLATE:
- if (state->ks_mode != K_XLATE) {
- /* make lock key state and LED state match */
- state->ks_state &= ~LOCK_MASK;
- state->ks_state |= KBD_LED_VAL(kbd);
- }
- /* FALL THROUGH */
- case K_RAW:
- case K_CODE:
- if (state->ks_mode != *(int *)arg) {
- pckbd_clear_state(kbd);
- state->ks_mode = *(int *)arg;
- }
- break;
- default:
- splx(s);
- return EINVAL;
- }
- break;
-
- case KDGETLED: /* get keyboard LED */
- *(int *)arg = KBD_LED_VAL(kbd);
- break;
- case KDSETLED: /* set keyboard LED */
- /* NOTE: lock key state in ks_state won't be changed */
- if (*(int *)arg & ~LOCK_MASK) {
- splx(s);
- return EINVAL;
- }
- i = *(int *)arg;
- /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
- if (kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
- if (i & ALKED)
- i |= CLKED;
- else
- i &= ~CLKED;
- }
- KBD_LED_VAL(kbd) = *(int *)arg;
- break;
-
- case KDGKBSTATE: /* get lock key state */
- *(int *)arg = state->ks_state & LOCK_MASK;
- break;
- case KDSKBSTATE: /* set lock key state */
- if (*(int *)arg & ~LOCK_MASK) {
- splx(s);
- return EINVAL;
- }
- state->ks_state &= ~LOCK_MASK;
- state->ks_state |= *(int *)arg;
- splx(s);
- /* set LEDs and quit */
- return pckbd_ioctl(kbd, KDSETLED, arg);
-
- case KDSETRAD: /* set keyboard repeat rate */
- break;
-
- case PIO_KEYMAP: /* set keyboard translation table */
- case PIO_KEYMAPENT: /* set keyboard translation table entry */
- case PIO_DEADKEYMAP: /* set accent key translation table */
- state->ks_accents = 0;
- /* FALL THROUGH */
- default:
- splx(s);
- return genkbd_commonioctl(kbd, cmd, arg);
- }
-
- splx(s);
- return 0;
-}
-
-/* lock the access to the keyboard */
-static int
-pckbd_lock(keyboard_t *kbd, int lock)
-{
- return kbdc_lock(((pckbd_state_t *)kbd->kb_data)->kbdc, lock);
-}
-
-/* clear the internal state of the keyboard */
-static void
-pckbd_clear_state(keyboard_t *kbd)
-{
- pckbd_state_t *state;
-
- state = (pckbd_state_t *)kbd->kb_data;
- state->ks_flags = 0;
- state->ks_state &= LOCK_MASK; /* preserve locking key state */
- state->ks_accents = 0;
- state->ks_composed_char = 0;
-}
-
-/* save the internal state */
-static int
-pckbd_get_state(keyboard_t *kbd, void *buf, size_t len)
-{
- if (len == 0)
- return sizeof(pckbd_state_t);
- if (len < sizeof(pckbd_state_t))
- return -1;
- bcopy(kbd->kb_data, buf, sizeof(pckbd_state_t));
- return 0;
-}
-
-/* set the internal state */
-static int
-pckbd_set_state(keyboard_t *kbd, void *buf, size_t len)
-{
- if (len < sizeof(pckbd_state_t))
- return ENOMEM;
- if (((pckbd_state_t *)kbd->kb_data)->kbdc
- != ((pckbd_state_t *)buf)->kbdc)
- return ENOMEM;
- bcopy(buf, kbd->kb_data, sizeof(pckbd_state_t));
- return 0;
-}
-
-/* local functions */
-
-static int
-probe_keyboard(KBDC kbdc, int flags)
-{
- return 0;
-}
-
-static int
-init_keyboard(KBDC kbdc, int *type, int flags)
-{
- *type = KB_OTHER;
- return 0;
-}
-
-/* keyboard I/O routines */
-
-/* retry count */
-#ifndef KBD_MAXRETRY
-#define KBD_MAXRETRY 3
-#endif
-
-/* timing parameters */
-#ifndef KBD_RESETDELAY
-#define KBD_RESETDELAY 200 /* wait 200msec after kbd/mouse reset */
-#endif
-#ifndef KBD_MAXWAIT
-#define KBD_MAXWAIT 5 /* wait 5 times at most after reset */
-#endif
-
-/* I/O recovery time */
-#define KBDC_DELAYTIME 37
-#define KBDD_DELAYTIME 37
-
-/* I/O ports */
-#define KBD_STATUS_PORT 2 /* status port, read */
-#define KBD_DATA_PORT 0 /* data port, read */
-
-/* status bits (KBD_STATUS_PORT) */
-#define KBDS_BUFFER_FULL 0x0002
-
-/* macros */
-
-#define kbdcp(p) ((struct kbdc_softc *)(p))
-
-/* local variables */
-
-static struct kbdc_softc kbdc_softc[NPCKBD] = { { 0 }, };
-
-/* associate a port number with a KBDC */
-
-static KBDC
-kbdc_open(int port)
-{
- if (port <= 0)
- port = IO_KBD;
-
- if (NPCKBD) {
- /* PC-98 has only one keyboard I/F */
- kbdc_softc[0].port = port;
- kbdc_softc[0].lock = FALSE;
- return (KBDC)&kbdc_softc[0];
- }
- return NULL; /* You didn't include sc driver in your config file */
-}
-
-/* set/reset polling lock */
-static int
-kbdc_lock(KBDC p, int lock)
-{
- int prevlock;
-
- prevlock = kbdcp(p)->lock;
- kbdcp(p)->lock = lock;
-
- return (prevlock != lock);
-}
-
-/* check if any data is waiting to be processed */
-static int
-kbdc_data_ready(KBDC p)
-{
- return (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL);
-}
-
-/* wait for data from the keyboard */
-static int
-wait_for_kbd_data(struct kbdc_softc *kbdc)
-{
- /* CPU will stay inside the loop for 200msec at most */
- int retry = 10000;
- int port = kbdc->port;
-
- while (!(inb(port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL)) {
- DELAY(KBDD_DELAYTIME);
- DELAY(KBDC_DELAYTIME);
- if (--retry < 0)
- return 0;
- }
- DELAY(KBDD_DELAYTIME);
- return 1;
-}
-
-/* read one byte from the keyboard */
-static int
-read_kbd_data(KBDC p)
-{
- if (!wait_for_kbd_data(kbdcp(p)))
- return -1; /* timeout */
- DELAY(KBDC_DELAYTIME);
- return inb(kbdcp(p)->port + KBD_DATA_PORT);
-}
-
-/* read one byte from the keyboard, but return immediately if
- * no data is waiting
- */
-static int
-read_kbd_data_no_wait(KBDC p)
-{
- if (inb(kbdcp(p)->port + KBD_STATUS_PORT) & KBDS_BUFFER_FULL) {
- DELAY(KBDD_DELAYTIME);
- return inb(kbdcp(p)->port + KBD_DATA_PORT);
- }
- return -1; /* no data */
-}
-
-#endif /* NPCKBD > 0 */
diff --git a/sys/pc98/pc98/pcaudio.c b/sys/pc98/pc98/pcaudio.c
index 05ba0161b6aa..abffc8c418ef 100644
--- a/sys/pc98/pc98/pcaudio.c
+++ b/sys/pc98/pc98/pcaudio.c
@@ -25,7 +25,7 @@
* (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: pcaudio.c,v 1.19 1998/12/14 08:58:56 kato Exp $
+ * $Id: pcaudio.c,v 1.43 1998/09/15 18:16:37 sos Exp $
*/
#include "pca.h"
@@ -52,6 +52,11 @@
#include <i386/isa/isa_device.h>
#include <i386/isa/timerreg.h>
+#define DSP_ULAW_NOT_WANTED
+#include <i386/isa/sound/ulaw.h>
+#define LINEAR_ALAW_NOT_WANTED
+#include <i386/isa/sound/alaw.h>
+
#ifdef DEVFS
#include <sys/devfsext.h>
#endif /* DEVFS */
@@ -84,44 +89,6 @@ static char buffer2[BUF_SIZE];
static char buffer3[BUF_SIZE];
static char volume_table[256];
-#define DSP_ULAW_NOT_WANTED
-#include <i386/isa/snd/ulaw.h>
-
-static unsigned char alaw_linear[] = {
- 45, 214, 122, 133, 0, 255, 107, 149,
- 86, 171, 126, 129, 0, 255, 117, 138,
- 13, 246, 120, 135, 0, 255, 99, 157,
- 70, 187, 124, 131, 0, 255, 113, 142,
- 61, 198, 123, 132, 0, 255, 111, 145,
- 94, 163, 127, 128, 0, 255, 119, 136,
- 29, 230, 121, 134, 0, 255, 103, 153,
- 78, 179, 125, 130, 0, 255, 115, 140,
- 37, 222, 122, 133, 0, 255, 105, 151,
- 82, 175, 126, 129, 0, 255, 116, 139,
- 5, 254, 120, 135, 0, 255, 97, 159,
- 66, 191, 124, 131, 0, 255, 112, 143,
- 53, 206, 123, 132, 0, 255, 109, 147,
- 90, 167, 127, 128, 0, 255, 118, 137,
- 21, 238, 121, 134, 0, 255, 101, 155,
- 74, 183, 125, 130, 0, 255, 114, 141,
- 49, 210, 123, 133, 0, 255, 108, 148,
- 88, 169, 127, 129, 0, 255, 118, 138,
- 17, 242, 121, 135, 0, 255, 100, 156,
- 72, 185, 125, 131, 0, 255, 114, 142,
- 64, 194, 124, 132, 0, 255, 112, 144,
- 96, 161, 128, 128, 1, 255, 120, 136,
- 33, 226, 122, 134, 0, 255, 104, 152,
- 80, 177, 126, 130, 0, 255, 116, 140,
- 41, 218, 122, 133, 0, 255, 106, 150,
- 84, 173, 126, 129, 0, 255, 117, 139,
- 9, 250, 120, 135, 0, 255, 98, 158,
- 68, 189, 124, 131, 0, 255, 113, 143,
- 57, 202, 123, 132, 0, 255, 110, 146,
- 92, 165, 127, 128, 0, 255, 119, 137,
- 25, 234, 121, 134, 0, 255, 102, 154,
- 76, 181, 125, 130, 0, 255, 115, 141,
-};
-
#ifdef DEVFS
static void *pca_devfs_token;
static void *pcac_devfs_token;
@@ -198,7 +165,7 @@ pca_init(void)
pca_status.buf[1] = (unsigned char *)&buffer2[0];
pca_status.buf[2] = (unsigned char *)&buffer3[0];
pca_status.buffer = pca_status.buf[0];
- pca_status.in_use[0] = pca_status.in_use[1] = pca_status.in_use[2] = 0;
+ pca_status.in_use[0] = pca_status.in_use[1] = pca_status.in_use[3] = 0;
pca_status.current = 0;
pca_status.sample_rate = SAMPLE_RATE;
pca_status.scale = (pca_status.sample_rate << 8) / INTERRUPT_RATE;
@@ -602,4 +569,5 @@ static void pca_drvinit(void *unused)
SYSINIT(pcadev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,pca_drvinit,NULL)
+
#endif
diff --git a/sys/pc98/pc98/scvidctl.c b/sys/pc98/pc98/scvidctl.c
deleted file mode 100644
index 77eba9811ce8..000000000000
--- a/sys/pc98/pc98/scvidctl.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*-
- * Copyright (c) 1998 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
- * 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 as
- * the first lines of this file unmodified.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $Id: scvidctl.c,v 1.1 1998/12/16 14:57:37 kato Exp $
- */
-
-#include "sc.h"
-#include "opt_syscons.h"
-
-#if NSC > 0
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/signalvar.h>
-#include <sys/tty.h>
-#include <sys/kernel.h>
-
-#include <machine/apm_bios.h>
-#include <machine/console.h>
-
-#include <dev/fb/fbreg.h>
-
-#include <pc98/pc98/syscons.h>
-
-/* for compatibility with previous versions */
-typedef struct old_video_adapter {
- int va_index;
- int va_type;
- int va_flags;
-#define V_ADP_COLOR (1<<0)
-#define V_ADP_MODECHANGE (1<<1)
-#define V_ADP_STATESAVE (1<<2)
-#define V_ADP_STATELOAD (1<<3)
-#define V_ADP_FONT (1<<4)
-#define V_ADP_PALETTE (1<<5)
-#define V_ADP_BORDER (1<<6)
-#define V_ADP_VESA (1<<7)
- int va_crtc_addr;
- u_int va_window; /* virtual address */
- size_t va_window_size;
- size_t va_window_gran;
- u_int va_buffer; /* virtual address */
- size_t va_buffer_size;
- int va_initial_mode;
- int va_initial_bios_mode;
- int va_mode;
-} old_video_adapter_t;
-
-#define OLD_CONS_ADPINFO _IOWR('c', 101, old_video_adapter_t)
-
-/* variables */
-extern scr_stat *cur_console;
-extern int fonts_loaded;
-extern int sc_history_size;
-extern u_char palette[];
-
-int
-sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize,
- int fontsize)
-{
- video_info_t info;
- int error;
- int s;
- int i;
-
- if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info))
- return ENODEV;
-
- /* adjust argument values */
- if (fontsize <= 0)
- fontsize = info.vi_cheight;
- if (fontsize < 14) {
- fontsize = 8;
- if (!(fonts_loaded & FONT_8))
- return EINVAL;
- } else if (fontsize >= 16) {
- fontsize = 16;
- if (!(fonts_loaded & FONT_16))
- return EINVAL;
- } else {
- fontsize = 14;
- if (!(fonts_loaded & FONT_14))
- return EINVAL;
- }
- if ((xsize <= 0) || (xsize > info.vi_width))
- xsize = info.vi_width;
- if ((ysize <= 0) || (ysize > info.vi_height))
- ysize = info.vi_height;
-
- /* stop screen saver, etc */
- s = spltty();
- if ((error = sc_clean_up(scp))) {
- splx(s);
- return error;
- }
-
- /* set up scp */
- if (scp->history != NULL)
- i = imax(scp->history_size / scp->xsize
- - imax(sc_history_size, scp->ysize), 0);
- else
- i = 0;
- /*
- * This is a kludge to fend off scrn_update() while we
- * muck around with scp. XXX
- */
- scp->status |= UNKNOWN_MODE;
- scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
- scp->mode = mode;
- scp->font_size = fontsize;
- scp->xsize = xsize;
- scp->ysize = ysize;
- scp->xoff = 0;
- scp->yoff = 0;
- scp->xpixel = scp->xsize*8;
- scp->ypixel = scp->ysize*fontsize;
-
- /* allocate buffers */
- sc_alloc_scr_buffer(scp, TRUE, TRUE);
- if (ISMOUSEAVAIL(scp->adp->va_flags))
- sc_alloc_cut_buffer(scp, FALSE);
- sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
- splx(s);
-
- if (scp == cur_console)
- set_mode(scp);
- scp->status &= ~UNKNOWN_MODE;
-
- if (tp == NULL)
- return 0;
- if (tp->t_winsize.ws_col != scp->xsize
- || tp->t_winsize.ws_row != scp->ysize) {
- tp->t_winsize.ws_col = scp->xsize;
- tp->t_winsize.ws_row = scp->ysize;
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- }
-
- return 0;
-}
-
-int
-sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode)
-{
- video_info_t info;
- int error;
- int s;
-
- if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info))
- return ENODEV;
-
- /* stop screen saver, etc */
- s = spltty();
- if ((error = sc_clean_up(scp))) {
- splx(s);
- return error;
- }
-
- /* set up scp */
- scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE);
- scp->status &= ~PIXEL_MODE;
- scp->mode = mode;
- scp->xoff = 0;
- scp->yoff = 0;
- scp->xpixel = info.vi_width;
- scp->ypixel = info.vi_height;
- scp->xsize = info.vi_width/8;
- scp->ysize = info.vi_height/info.vi_cheight;
- scp->font_size = FONT_NONE;
- /* move the mouse cursor at the center of the screen */
- sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
- splx(s);
-
- if (scp == cur_console)
- set_mode(scp);
- /* clear_graphics();*/
- scp->status &= ~UNKNOWN_MODE;
-
- if (tp == NULL)
- return 0;
- if (tp->t_winsize.ws_xpixel != scp->xpixel
- || tp->t_winsize.ws_ypixel != scp->ypixel) {
- tp->t_winsize.ws_xpixel = scp->xpixel;
- tp->t_winsize.ws_ypixel = scp->ypixel;
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- }
-
- return 0;
-}
-
-int
-sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize,
- int fontsize)
-{
- video_info_t info;
- int error;
- int s;
- int i;
-
- if ((*vidsw[scp->ad]->get_info)(scp->adp, scp->mode, &info))
- return ENODEV; /* this shouldn't happen */
-
-#ifdef SC_VIDEO_DEBUG
- if (scp->scr_buf != NULL) {
- printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
- scp->mode, xsize, ysize, fontsize);
- }
-#endif
-
- /* adjust argument values */
- if ((fontsize <= 0) || (fontsize == FONT_NONE))
- fontsize = info.vi_cheight;
- if (fontsize < 14) {
- fontsize = 8;
- if (!(fonts_loaded & FONT_8))
- return EINVAL;
- } else if (fontsize >= 16) {
- fontsize = 16;
- if (!(fonts_loaded & FONT_16))
- return EINVAL;
- } else {
- fontsize = 14;
- if (!(fonts_loaded & FONT_14))
- return EINVAL;
- }
- if (xsize <= 0)
- xsize = info.vi_width/8;
- if (ysize <= 0)
- ysize = info.vi_height/fontsize;
-
-#ifdef SC_VIDEO_DEBUG
- if (scp->scr_buf != NULL) {
- printf("set_pixel_mode(): mode:%x, col:%d, row:%d, font:%d\n",
- scp->mode, xsize, ysize, fontsize);
- printf("set_pixel_mode(): window:%x, %dx%d, xoff:%d, yoff:%d\n",
- scp->adp->va_window, info.vi_width, info.vi_height,
- (info.vi_width/8 - xsize)/2,
- (info.vi_height/fontsize - ysize)/2);
- }
-#endif
-
- if ((info.vi_width < xsize*8) || (info.vi_height < ysize*fontsize))
- return EINVAL;
-
- /* only 16 color, 4 plane modes are supported XXX */
- if ((info.vi_depth != 4) || (info.vi_planes != 4))
- return ENODEV;
-
- /*
- * set_pixel_mode() currently does not support video modes whose
- * memory size is larger than 64K. Because such modes require
- * bank switching to access the entire screen. XXX
- */
- if (info.vi_width*info.vi_height/8 > info.vi_window_size)
- return ENODEV;
-
- /* stop screen saver, etc */
- s = spltty();
- if ((error = sc_clean_up(scp))) {
- splx(s);
- return error;
- }
-
- /* set up scp */
- if (scp->history != NULL)
- i = imax(scp->history_size / scp->xsize
- - imax(sc_history_size, scp->ysize), 0);
- else
- i = 0;
- scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
- scp->status &= ~(GRAPHICS_MODE | MOUSE_ENABLED);
- scp->xsize = xsize;
- scp->ysize = ysize;
- scp->font_size = fontsize;
- scp->xoff = (scp->xpixel/8 - xsize)/2;
- scp->yoff = (scp->ypixel/fontsize - ysize)/2;
-
- /* allocate buffers */
- sc_alloc_scr_buffer(scp, TRUE, TRUE);
- if (ISMOUSEAVAIL(scp->adp->va_flags))
- sc_alloc_cut_buffer(scp, FALSE);
- sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
- splx(s);
-
- if (scp == cur_console)
- set_border(scp, scp->border);
-
- scp->status &= ~UNKNOWN_MODE;
-
-#ifdef SC_VIDEO_DEBUG
- printf("set_pixel_mode(): status:%x\n", scp->status);
-#endif
-
- if (tp == NULL)
- return 0;
- if (tp->t_winsize.ws_col != scp->xsize
- || tp->t_winsize.ws_row != scp->ysize) {
- tp->t_winsize.ws_col = scp->xsize;
- tp->t_winsize.ws_row = scp->ysize;
- pgsignal(tp->t_pgrp, SIGWINCH, 1);
- }
-
- return 0;
-}
-
-int
-sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p)
-{
- scr_stat *scp;
- int error;
- int s;
-
- scp = sc_get_scr_stat(tp->t_dev);
-
- switch (cmd) {
-
- case CONS_CURRENT: /* get current adapter type */
- if (scp->adp == NULL)
- return ENODEV;
- *(int *)data = scp->adp->va_type;
- return 0;
-
- case CONS_CURRENTADP: /* get current adapter index */
- *(int *)data = scp->ad;
- return 0;
-
- case OLD_CONS_ADPINFO: /* adapter information */
- if (scp->adp == NULL)
- return ENODEV;
- ((old_video_adapter_t *)data)->va_index = scp->adp->va_index;
- ((old_video_adapter_t *)data)->va_type = scp->adp->va_type;
- ((old_video_adapter_t *)data)->va_flags = scp->adp->va_flags;
- ((old_video_adapter_t *)data)->va_crtc_addr = scp->adp->va_crtc_addr;
- ((old_video_adapter_t *)data)->va_window = scp->adp->va_window;
- ((old_video_adapter_t *)data)->va_window_size
- = scp->adp->va_window_size;
- ((old_video_adapter_t *)data)->va_window_gran
- = scp->adp->va_window_gran;
- ((old_video_adapter_t *)data)->va_buffer = scp->adp->va_buffer;
- ((old_video_adapter_t *)data)->va_buffer_size
- = scp->adp->va_buffer_size;
- ((old_video_adapter_t *)data)->va_mode = scp->adp->va_mode;
- ((old_video_adapter_t *)data)->va_initial_mode
- = scp->adp->va_initial_mode;
- ((old_video_adapter_t *)data)->va_initial_bios_mode
- = scp->adp->va_initial_bios_mode;
- return 0;
-
- case CONS_ADPINFO: /* adapter information */
- if (scp->adp == NULL)
- return ENODEV;
- ((video_adapter_info_t *)data)->va_index = scp->adp->va_index;
- ((video_adapter_info_t *)data)->va_type = scp->adp->va_type;
- bcopy(scp->adp->va_name, ((video_adapter_info_t *)data)->va_name,
- imin(strlen(scp->adp->va_name) + 1,
- sizeof(((video_adapter_info_t *)data)->va_name)));
- ((video_adapter_info_t *)data)->va_unit = scp->adp->va_unit;
- ((video_adapter_info_t *)data)->va_flags = scp->adp->va_flags;
- ((video_adapter_info_t *)data)->va_io_base = scp->adp->va_io_base;
- ((video_adapter_info_t *)data)->va_io_size = scp->adp->va_io_size;
- ((video_adapter_info_t *)data)->va_crtc_addr = scp->adp->va_crtc_addr;
- ((video_adapter_info_t *)data)->va_mem_base = scp->adp->va_mem_base;
- ((video_adapter_info_t *)data)->va_mem_size = scp->adp->va_mem_size;
- ((video_adapter_info_t *)data)->va_window = scp->adp->va_window;
- ((video_adapter_info_t *)data)->va_window_size
- = scp->adp->va_window_size;
- ((video_adapter_info_t *)data)->va_window_gran
- = scp->adp->va_window_gran;
- ((video_adapter_info_t *)data)->va_buffer = scp->adp->va_buffer;
- ((video_adapter_info_t *)data)->va_buffer_size
- = scp->adp->va_buffer_size;
- ((video_adapter_info_t *)data)->va_mode = scp->adp->va_mode;
- ((video_adapter_info_t *)data)->va_mode_flags = scp->adp->va_mode_flags;
- ((video_adapter_info_t *)data)->va_initial_mode
- = scp->adp->va_initial_mode;
- ((video_adapter_info_t *)data)->va_initial_bios_mode
- = scp->adp->va_initial_bios_mode;
- return 0;
-
- case CONS_GET: /* get current video mode */
- *(int *)data = scp->mode;
- return 0;
-
- case CONS_MODEINFO: /* get mode information */
- return ((*vidsw[scp->ad]->get_info)(scp->adp,
- ((video_info_t *)data)->vi_mode, (video_info_t *)data)
- ? ENODEV : 0);
-
- case CONS_FINDMODE: /* find a matching video mode */
- return ((*vidsw[scp->ad]->query_mode)(scp->adp, (video_info_t *)data)
- ? ENODEV : 0);
-
- case CONS_SETWINORG:
- return ((*vidsw[scp->ad]->set_win_org)(scp->adp, *(u_int *)data)
- ? ENODEV : 0);
-
- /* generic text modes */
- case SW_TEXT_80x25: case SW_TEXT_80x30:
- case SW_TEXT_80x43: case SW_TEXT_80x50:
- case SW_TEXT_80x60:
- /* FALL THROUGH */
-
- /* VGA TEXT MODES */
- case SW_VGA_C40x25:
- case SW_VGA_C80x25: case SW_VGA_M80x25:
- case SW_VGA_C80x30: case SW_VGA_M80x30:
- case SW_VGA_C80x50: case SW_VGA_M80x50:
- case SW_VGA_C80x60: case SW_VGA_M80x60:
- case SW_B40x25: case SW_C40x25:
- case SW_B80x25: case SW_C80x25:
- case SW_ENH_B40x25: case SW_ENH_C40x25:
- case SW_ENH_B80x25: case SW_ENH_C80x25:
- case SW_ENH_B80x43: case SW_ENH_C80x43:
- case SW_EGAMONO80x25:
-
-#ifdef PC98
- /* PC98 TEXT MODES */
- case SW_PC98_80x25:
- case SW_PC98_80x30:
-#endif
- if (!(scp->adp->va_flags & V_ADP_MODECHANGE))
- return ENODEV;
- return sc_set_text_mode(scp, tp, cmd & 0xff, 0, 0, 0);
-
- /* GRAPHICS MODES */
- case SW_BG320: case SW_BG640:
- case SW_CG320: case SW_CG320_D: case SW_CG640_E:
- case SW_CG640x350: case SW_ENH_CG640:
- case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
- case SW_VGA_MODEX:
- if (!(scp->adp->va_flags & V_ADP_MODECHANGE))
- return ENODEV;
- return sc_set_graphics_mode(scp, tp, cmd & 0xff);
-
- case KDSETMODE: /* set current mode of this (virtual) console */
- switch (*(int *)data) {
- case KD_TEXT: /* switch to TEXT (known) mode */
- /*
- * If scp->mode is of graphics modes, we don't know which
- * text mode to switch back to...
- */
- if (scp->status & GRAPHICS_MODE)
- return EINVAL;
- /* restore fonts & palette ! */
-#if 0
- if (ISFONTAVAIL(scp->adp->va_flags)
- && !(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
- /*
- * FONT KLUDGE
- * Don't load fonts for now... XXX
- */
- if (fonts_loaded & FONT_8)
- copy_font(scp, LOAD, 8, font_8);
- if (fonts_loaded & FONT_14)
- copy_font(scp, LOAD, 14, font_14);
- if (fonts_loaded & FONT_16)
- copy_font(scp, LOAD, 16, font_16);
- }
-#endif
- load_palette(scp->adp, palette);
-
- /* move hardware cursor out of the way */
- (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, -1, -1);
-
- /* FALL THROUGH */
-
- case KD_TEXT1: /* switch to TEXT (known) mode */
- /*
- * If scp->mode is of graphics modes, we don't know which
- * text/pixel mode to switch back to...
- */
- if (scp->status & GRAPHICS_MODE)
- return EINVAL;
- s = spltty();
- if ((error = sc_clean_up(scp))) {
- splx(s);
- return error;
- }
-#ifndef PC98
- scp->status |= UNKNOWN_MODE;
- splx(s);
- /* no restore fonts & palette */
- if (scp == cur_console)
- set_mode(scp);
- sc_clear_screen(scp);
- scp->status &= ~UNKNOWN_MODE;
-#else /* PC98 */
- scp->status &= ~UNKNOWN_MODE;
- /* no restore fonts & palette */
- if (scp == cur_console)
- set_mode(scp);
- sc_clear_screen(scp);
- splx(s);
-#endif /* PC98 */
- return 0;
-
- case KD_PIXEL: /* pixel (raster) display */
- if (!(scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
- return EINVAL;
- if (scp->status & GRAPHICS_MODE)
- return sc_set_pixel_mode(scp, tp, scp->xsize, scp->ysize,
- scp->font_size);
- s = spltty();
- if ((error = sc_clean_up(scp))) {
- splx(s);
- return error;
- }
- scp->status |= (UNKNOWN_MODE | PIXEL_MODE);
- splx(s);
- if (scp == cur_console) {
- set_mode(scp);
- load_palette(scp->adp, palette);
- }
- sc_clear_screen(scp);
- scp->status &= ~UNKNOWN_MODE;
- return 0;
-
- case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
- s = spltty();
- if ((error = sc_clean_up(scp))) {
- splx(s);
- return error;
- }
- scp->status |= UNKNOWN_MODE;
- splx(s);
-#ifdef PC98
- if (scp == cur_console)
- set_mode(scp);
-#endif
- return 0;
-
- default:
- return EINVAL;
- }
- /* NOT REACHED */
-
- case KDRASTER: /* set pixel (raster) display mode */
- if (ISUNKNOWNSC(scp) || ISTEXTSC(scp))
- return ENODEV;
- return sc_set_pixel_mode(scp, tp, ((int *)data)[0], ((int *)data)[1],
- ((int *)data)[2]);
-
- case KDGETMODE: /* get current mode of this (virtual) console */
- /*
- * From the user program's point of view, KD_PIXEL is the same
- * as KD_TEXT...
- */
- *data = ISGRAPHSC(scp) ? KD_GRAPHICS : KD_TEXT;
- return 0;
-
- case KDSBORDER: /* set border color of this (virtual) console */
- scp->border = *data;
- if (scp == cur_console)
- set_border(scp, scp->border);
- return 0;
- }
-
- return ENOIOCTL;
-}
-
-#endif /* NSC > 0 */
diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c
index 97ac3ad3b384..abce135c8193 100644
--- a/sys/pc98/pc98/sio.c
+++ b/sys/pc98/pc98/sio.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.75 1999/01/16 11:42:16 kato Exp $
+ * $Id: sio.c,v 1.66 1998/08/28 12:44:49 kato Exp $
*/
#include "opt_comconsole.h"
@@ -74,9 +74,9 @@
*
* 1) config
* options COM_MULTIPORT #if using MC16550II
- * device sio0 at nec? port 0x30 tty irq 4 #internal
- * device sio1 at nec? port 0xd2 tty irq 5 flags 0x101 #mc1
- * device sio2 at nec? port 0x8d2 tty flags 0x101 #mc2
+ * device sio0 at nec? port 0x30 tty irq 4 vector siointr #internal
+ * device sio1 at nec? port 0xd2 tty irq 5 flags 0x101 vector siointr #mc1
+ * device sio2 at nec? port 0x8d2 tty flags 0x101 vector siointr #mc2
* # ~~~~~iobase ~~multi port flag
* # ~ master device is sio1
* 2) device
@@ -103,36 +103,21 @@
* # options COM_MULTIPORT # support for MICROCORE MC16550II
* ... comment-out this line, which will conflict with B98_01.
* options "B98_01" # support for AIWA B98-01
- * device sio1 at nec? port 0x00d1 tty irq ?
- * device sio2 at nec? port 0x00d5 tty irq ?
+ * device sio1 at nec? port 0x00d1 tty irq ? vector siointr
+ * device sio2 at nec? port 0x00d5 tty irq ? vector siointr
* ... you can leave these lines `irq ?', irq will be autodetected.
*/
-/*
- * Modified by Y.Takahashi of Kogakuin University.
- */
-
#ifdef PC98
-#define COM_IF_INTERNAL 0x00
-#define COM_IF_PC9861K_1 0x01
-#define COM_IF_PC9861K_2 0x02
-#define COM_IF_IND_SS_1 0x03
-#define COM_IF_IND_SS_2 0x04
-#define COM_IF_PIO9032B_1 0x05
-#define COM_IF_PIO9032B_2 0x06
-#define COM_IF_B98_01_1 0x07
-#define COM_IF_B98_01_2 0x08
-#define COM_IF_END1 COM_IF_B98_01_2
-#define COM_IF_RSA98 0x10 /* same as COM_IF_NS16550 */
-#define COM_IF_NS16550 0x11
-#define COM_IF_SECOND_CCU 0x12 /* same as COM_IF_NS16550 */
-#define COM_IF_MC16550II 0x13
-#define COM_IF_MCRS98 0x14 /* same as COM_IF_MC16550II */
-#define COM_IF_RSB3000 0x15
-#define COM_IF_RSB384 0x16
-#define COM_IF_MODEM_CARD 0x17 /* same as COM_IF_NS16550 */
-#define COM_IF_RSA98III 0x18
-#define COM_IF_ESP98 0x19
-#define COM_IF_END2 COM_IF_ESP98
+#define MC16550 0
+#define COM_IF_INTERNAL 1
+#if 0
+#define COM_IF_PC9861K 2
+#define COM_IF_PIO9032B 3
+#endif
+#ifdef B98_01
+#undef COM_MULTIPORT /* COM_MULTIPORT will conflict with B98_01 */
+#define COM_IF_B98_01 4
+#endif /* B98_01 */
#endif /* PC98 */
#include <sys/param.h>
@@ -154,33 +139,28 @@
#include <machine/clock.h>
#include <machine/ipl.h>
-#ifndef SMP
-#include <machine/lock.h>
-#endif
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
#include <i386/isa/icu.h>
+#include <i386/isa/isa_device.h>
+#include <pc98/pc98/sioreg.h>
#include <i386/isa/ic/i8251.h>
#else
#include <i386/isa/isa.h>
-#endif
#include <i386/isa/isa_device.h>
#include <i386/isa/sioreg.h>
+#endif
#include <i386/isa/intr_machdep.h>
#ifdef COM_ESP
#include <i386/isa/ic/esp.h>
#endif
#include <i386/isa/ic/ns16550.h>
-#ifdef PC98
-#include <i386/isa/ic/rsa.h>
-#endif
#include "card.h"
#if NCARD > 0
-#include <sys/module.h>
#include <pccard/cardinfo.h>
#include <pccard/slot.h>
#endif
@@ -236,11 +216,9 @@
#define COM_IIR_TXRDYBUG(dev) ((dev)->id_flags & COM_C_IIR_TXRDYBUG)
#define COM_FIFOSIZE(dev) (((dev)->id_flags & 0xff000000) >> 24)
-#ifdef PC98
-#define com_emr com_msr /* Extension mode register for RSB-2000/3000 */
-#else
+#ifndef PC98
#define com_scr 7 /* scratch register for 16450-16550 (R/W) */
-#endif
+#endif /* !PC98 */
/*
* Input buffer watermarks.
@@ -369,9 +347,6 @@ struct com_s {
#endif
Port_t int_id_port;
Port_t iobase;
-#ifdef PC98
- Port_t rsabase; /* iobase address of a I/O-DATA RSA board */
-#endif
Port_t modem_ctl_port;
Port_t line_status_port;
Port_t modem_status_port;
@@ -401,18 +376,6 @@ struct com_s {
* Ping-pong input buffers. The extra factor of 2 in the sizes is
* to allow for an error byte for each input byte.
*/
-#ifdef PC98
- u_long CE_INPUT_OFFSET;
- u_char *ibuf1;
- u_char *ibuf2;
-
- /*
- * Data area for output buffers. Someday we should build the output
- * buffer queue without copying data.
- */
- u_char *obuf1;
- u_char *obuf2;
-#else
#define CE_INPUT_OFFSET RS_IBUFSIZE
u_char ibuf1[2 * RS_IBUFSIZE];
u_char ibuf2[2 * RS_IBUFSIZE];
@@ -423,7 +386,6 @@ struct com_s {
*/
u_char obuf1[256];
u_char obuf2[256];
-#endif
#ifdef DEVFS
void *devfs_token_ttyd;
void *devfs_token_ttyl;
@@ -442,7 +404,6 @@ static int sioattach __P((struct isa_device *dev));
static timeout_t siobusycheck;
static timeout_t siodtrwakeup;
static void comhardclose __P((struct com_s *com));
-static ointhand2_t siointr;
static void siointr1 __P((struct com_s *com));
static int commctl __P((struct com_s *com, int bits, int how));
static int comparam __P((struct tty *tp, struct termios *t));
@@ -454,6 +415,9 @@ static timeout_t comwakeup;
static void disc_optim __P((struct tty *tp, struct termios *t,
struct com_s *com));
+#ifdef DSI_SOFT_MODEM
+static int LoadSoftModem __P((int unit,int base_io, u_long size, u_char *ptr));
+#endif /* DSI_SOFT_MODEM */
static char driver_name[] = "sio";
@@ -503,9 +467,28 @@ struct siodev {
short if_type;
short irq;
Port_t cmd, sts, ctrl, mod;
-};
+ };
static int sysclock;
-
+static short port_table[5][3] = {
+ {0x30, 0xb1, 0xb9},
+ {0x32, 0xb3, 0xbb},
+ {0x32, 0xb3, 0xbb},
+ {0x33, 0xb0, 0xb2},
+ {0x35, 0xb0, 0xb2}
+ };
+#define PC98SIO_data_port(ch) port_table[0][ch]
+#define PC98SIO_cmd_port(ch) port_table[1][ch]
+#define PC98SIO_sts_port(ch) port_table[2][ch]
+#define PC98SIO_in_modem_port(ch) port_table[3][ch]
+#define PC98SIO_intr_ctrl_port(ch) port_table[4][ch]
+#ifdef COM_IF_PIO9032B
+#define IO_COM_PIO9032B_2 0x0b8
+#define IO_COM_PIO9032B_3 0x0ba
+#endif /* COM_IF_PIO9032B */
+#ifdef COM_IF_B98_01
+#define IO_COM_B98_01_2 0x0d1
+#define IO_COM_B98_01_3 0x0d5
+#endif /* COM_IF_B98_01 */
#define COM_INT_DISABLE {int previpri; previpri=spltty();
#define COM_INT_ENABLE splx(previpri);}
#define IEN_TxFLAG IEN_Tx
@@ -514,8 +497,8 @@ static int sysclock;
#define PC98_CHECK_MODEM_INTERVAL (hz/10)
#define DCD_OFF_TOLERANCE 2
#define DCD_ON_RECOGNITION 2
-#define IS_8251(if_type) (!(if_type & 0x10))
-#define COM1_EXT_CLOCK 0x40000
+#define IS_8251(type) (type != MC16550)
+#define IS_PC98IN(adr) (adr == 0x30)
static void commint __P((dev_t dev));
static void com_tiocm_set __P((struct com_s *com, int msr));
@@ -539,9 +522,9 @@ static void pc98_i8251_set_cmd __P((struct com_s *com, int x));
static void pc98_i8251_or_cmd __P((struct com_s *com, int x));
static void pc98_i8251_clear_cmd __P((struct com_s *com, int x));
static void pc98_i8251_clear_or_cmd __P((struct com_s *com, int clr, int x));
-static int pc98_check_if_type __P((struct isa_device *dev, struct siodev *iod));
+static int pc98_check_if_type __P((int iobase, struct siodev *iod));
static void pc98_check_sysclock __P((void));
-static int pc98_set_ioport __P((struct com_s *com, int id_flags));
+static int pc98_set_ioport __P((struct com_s *com, int io_base));
#define com_int_Tx_disable(com) \
pc98_disable_i8251_interrupt(com,IEN_Tx|IEN_TxEMP)
@@ -560,7 +543,7 @@ static int pc98_set_ioport __P((struct com_s *com, int id_flags));
#define com_send_break_off(com) \
pc98_i8251_clear_cmd(com,CMD8251_SBRK)
-static struct speedtab pc98speedtab[] = { /* internal RS232C interface */
+struct speedtab pc98speedtab[] = { /* internal RS232C interface */
0, 0,
50, 50,
75, 75,
@@ -574,23 +557,16 @@ static struct speedtab pc98speedtab[] = { /* internal RS232C interface */
9600, 9600,
19200, 19200,
38400, 38400,
- 51200, 51200,
76800, 76800,
20800, 20800,
- 31200, 31200,
41600, 41600,
+ 15600, 15600,
+ 31200, 31200,
62400, 62400,
-1, -1
};
-static struct speedtab pc98fast_speedtab[] = {
- 9600, 0x80 | COMBRD(9600),
- 19200, 0x80 | COMBRD(19200),
- 38400, 0x80 | COMBRD(38400),
- 57600, 0x80 | COMBRD(57600),
- 115200, 0x80 | COMBRD(115200),
- -1, -1
-};
-static struct speedtab comspeedtab_pio9032b[] = {
+#ifdef COM_IF_PIO9032B
+struct speedtab comspeedtab_pio9032b[] = {
300, 6,
600, 5,
1200, 4,
@@ -601,82 +577,26 @@ static struct speedtab comspeedtab_pio9032b[] = {
38400, 7,
-1, -1
};
-static struct speedtab comspeedtab_b98_01[] = {
- 75, 11,
- 150, 10,
- 300, 9,
- 600, 8,
- 1200, 7,
- 2400, 6,
- 4800, 5,
- 9600, 4,
- 19200, 3,
- 38400, 2,
- 76800, 1,
- 153600, 0,
- -1, -1
-};
-static struct speedtab comspeedtab_mc16550[] = {
- 300, 1536,
- 600, 768,
- 1200, 384,
- 2400, 192,
- 4800, 96,
- 9600, 48,
- 19200, 24,
- 38400, 12,
- 57600, 8,
- 115200, 4,
- 153600, 3,
- 230400, 2,
- 460800, 1,
+#endif
+
+#ifdef COM_IF_B98_01
+struct speedtab comspeedtab_b98_01[] = {
+ 0, 0,
+ 75, 15,
+ 150, 14,
+ 300, 13,
+ 600, 12,
+ 1200, 11,
+ 2400, 10,
+ 4800, 9,
+ 9600, 8,
+ 19200, 7,
+ 38400, 6,
+ 76800, 5,
+ 153600, 4,
-1, -1
};
-static struct speedtab comspeedtab_rsb384[] = {
- 300, 3840,
- 600, 1920,
- 1200, 960,
- 2400, 480,
- 4800, 240,
- 9600, 120,
- 19200, 60,
- 38400, 30,
- 57600, 20,
- 115200, 10,
- 128000, 9,
- 144000, 8,
- 192000, 6,
- 230400, 5,
- 288000, 4,
- 384000, 3,
- 576000, 2,
- 1152000, 1,
- -1, -1
-};
-static struct speedtab comspeedtab_rsa[] = {
- { 0, 0 },
- { 50, COMBRD_RSA(50) },
- { 75, COMBRD_RSA(75) },
- { 110, COMBRD_RSA(110) },
- { 134, COMBRD_RSA(134) },
- { 150, COMBRD_RSA(150) },
- { 200, COMBRD_RSA(200) },
- { 300, COMBRD_RSA(300) },
- { 600, COMBRD_RSA(600) },
- { 1200, COMBRD_RSA(1200) },
- { 1800, COMBRD_RSA(1800) },
- { 2400, COMBRD_RSA(2400) },
- { 4800, COMBRD_RSA(4800) },
- { 9600, COMBRD_RSA(9600) },
- { 19200, COMBRD_RSA(19200) },
- { 38400, COMBRD_RSA(38400) },
- { 57600, COMBRD_RSA(57600) },
- { 115200, COMBRD_RSA(115200) },
- { 230400, COMBRD_RSA(230400) },
- { 460800, COMBRD_RSA(460800) },
- { 921600, COMBRD_RSA(921600) },
- { -1, -1 }
-};
+#endif
#endif /* PC98 */
static struct speedtab comspeedtab[] = {
@@ -701,100 +621,10 @@ static struct speedtab comspeedtab[] = {
{ -1, -1 }
};
-#ifdef PC98
-struct {
- char *name;
- short port_table[7];
- short irr_mask;
- struct speedtab *speedtab;
- short check_irq;
-} if_8251_type[] = {
- /* COM_IF_INTERNAL */
- { " (internal)", {0x30, 0x32, 0x32, 0x33, 0x35, -1, -1},
- -1, pc98speedtab, 1 },
- /* COM_IF_PC9861K_1 */
- { " (PC9861K)", {0xb1, 0xb3, 0xb3, 0xb0, 0xb0, -1, -1},
- 3, NULL, 1 },
- /* COM_IF_PC9861K_2 */
- { " (PC9861K)", {0xb9, 0xbb, 0xbb, 0xb2, 0xb2, -1, -1},
- 3, NULL, 1 },
- /* COM_IF_IND_SS_1 */
- { " (IND-SS)", {0xb1, 0xb3, 0xb3, 0xb0, 0xb0, 0xb3, -1},
- 3, comspeedtab_mc16550, 1 },
- /* COM_IF_IND_SS_2 */
- { " (IND-SS)", {0xb9, 0xbb, 0xbb, 0xb2, 0xb2, 0xbb, -1},
- 3, comspeedtab_mc16550, 1 },
- /* COM_IF_PIO9032B_1 */
- { " (PIO9032B)", {0xb1, 0xb3, 0xb3, 0xb0, 0xb0, 0xb8, -1},
- 7, comspeedtab_pio9032b, 1 },
- /* COM_IF_PIO9032B_2 */
- { " (PIO9032B)", {0xb9, 0xbb, 0xbb, 0xb2, 0xb2, 0xba, -1},
- 7, comspeedtab_pio9032b, 1 },
- /* COM_IF_B98_01_1 */
- { " (B98-01)", {0xb1, 0xb3, 0xb3, 0xb0, 0xb0, 0xd1, 0xd3},
- 7, comspeedtab_b98_01, 0 },
- /* COM_IF_B98_01_2 */
- { " (B98-01)", {0xb9, 0xbb, 0xbb, 0xb2, 0xb2, 0xd5, 0xd7},
- 7, comspeedtab_b98_01, 0 },
-};
-#define PC98SIO_data_port(type) (if_8251_type[type].port_table[0])
-#define PC98SIO_cmd_port(type) (if_8251_type[type].port_table[1])
-#define PC98SIO_sts_port(type) (if_8251_type[type].port_table[2])
-#define PC98SIO_in_modem_port(type) (if_8251_type[type].port_table[3])
-#define PC98SIO_intr_ctrl_port(type) (if_8251_type[type].port_table[4])
-#define PC98SIO_baud_rate_port(type) (if_8251_type[type].port_table[5])
-#define PC98SIO_func_port(type) (if_8251_type[type].port_table[6])
-
-struct {
- char *name;
- short irr_read;
- short irr_write;
- short port_shift;
- short io_size;
- struct speedtab *speedtab;
-} if_16550a_type[] = {
- /* COM_IF_RSA98 */
- { " (RSA-98)", -1, -1, 0, IO_COMSIZE, comspeedtab },
- /* COM_IF_NS16550 */
- { "", -1, -1, 0, IO_COMSIZE, comspeedtab },
- /* COM_IF_SECOND_CCU */
- { "", -1, -1, 0, IO_COMSIZE, comspeedtab },
- /* COM_IF_MC16550II */
- { " (MC16550II)", -1, 0x1000, 8, 1, comspeedtab_mc16550 },
- /* COM_IF_MCRS98 */
- { " (MC-RS98)", -1, 0x1000, 8, 1, comspeedtab_mc16550 },
- /* COM_IF_RSB3000 */
- { " (RSB-3000)", 0xbf, -1, 1, 1, comspeedtab_rsb384 },
- /* COM_IF_RSB384 */
- { " (RSB-384)", 0xbf, -1, 1, 1, comspeedtab_rsb384 },
- /* COM_IF_MODEM_CARD */
- { "", -1, -1, 0, IO_COMSIZE, comspeedtab },
- /* COM_IF_RSA98III */
- { " (RSA-98III)", -1, -1, 0, 16, comspeedtab_rsa },
- /* COM_IF_ESP98 */
- { " (ESP98)", -1, -1, 1, 1, comspeedtab_mc16550 },
-};
-#endif /* PC98 */
-
#ifdef COM_ESP
-#ifdef PC98
-
-/* XXX configure this properly. */
-static Port_t likely_com_ports[] = { 0, 0xb0, 0xb1, 0 };
-static Port_t likely_esp_ports[] = { 0xc0d0, 0 };
-
-#define ESP98_CMD1 (ESP_CMD1 * 0x100)
-#define ESP98_CMD2 (ESP_CMD2 * 0x100)
-#define ESP98_STATUS1 (ESP_STATUS1 * 0x100)
-#define ESP98_STATUS2 (ESP_STATUS2 * 0x100)
-
-#else /* PC98 */
-
/* XXX configure this properly. */
static Port_t likely_com_ports[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, };
static Port_t likely_esp_ports[] = { 0x140, 0x180, 0x280, 0 };
-
-#endif /* PC98 */
#endif
/*
@@ -865,7 +695,17 @@ static int sioinit __P((struct pccard_devinfo *));
static void siounload __P((struct pccard_devinfo *));
static int card_intr __P((struct pccard_devinfo *));
-PCCARD_MODULE(sio, sioinit, siounload, card_intr, 0, tty_imask);
+static struct pccard_device sio_info = {
+ driver_name,
+ sioinit,
+ siounload,
+ card_intr,
+ 0, /* Attributes - presently unused */
+ &tty_imask /* Interrupt mask for device */
+ /* XXX - Should this also include net_imask? */
+};
+
+DATA_SET(pccarddrv_set, sio_info);
/*
* Initialize the device - called from Slot manager.
@@ -932,9 +772,6 @@ siounload(struct pccard_devinfo *devi)
ttwwakeup(com->tp);
} else {
com_addr(com->unit) = NULL;
-#ifdef PC98
- bzero(com->ibuf1, com->CE_INPUT_OFFSET * 6);
-#endif
bzero(com, sizeof *com);
free(com,M_TTYS);
printf("sio%d: unload,gone\n", devi->isahd.id_unit);
@@ -977,9 +814,7 @@ sioprobe(dev)
int irqout=0;
int ret = 0;
int tmp;
- int port_shift = 0;
- struct siodev iod;
- Port_t rsabase = NULL;
+ struct siodev iod;
#endif
if (!already_init) {
@@ -990,26 +825,13 @@ sioprobe(dev)
* XXX the gate enable is elsewhere for some multiports.
*/
for (xdev = isa_devtab_tty; xdev->id_driver != NULL; xdev++)
+ if (xdev->id_driver == &siodriver && xdev->id_enabled)
#ifdef PC98
- if (xdev->id_driver == &siodriver && xdev->id_enabled) {
- tmp = (xdev->id_flags >> 24) & 0xff;
- if (IS_8251(tmp))
- outb((xdev->id_iobase & 0xff00) | PC98SIO_cmd_port(tmp & 0x0f), 0xf2);
- else
- if (tmp == COM_IF_RSA98III) {
- rsabase = xdev->id_iobase & 0xfff0;
-#if 0
- if (rsabase != xdev->id_iobase)
- return(0);
+ if (IS_PC98IN(xdev->id_iobase))
+ outb(xdev->id_iobase + 2, 0xf2);
+ else
#endif
- outb(xdev->id_iobase + 8 + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
- } else
- outb(xdev->id_iobase + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
- }
-#else
- if (xdev->id_driver == &siodriver && xdev->id_enabled)
outb(xdev->id_iobase + com_mcr, 0);
-#endif
already_init = TRUE;
}
@@ -1020,15 +842,14 @@ sioprobe(dev)
#ifdef PC98
DELAY(10);
-
/*
* If the port is i8251 UART (internal, B98_01)
*/
- if (pc98_check_if_type(dev, &iod) == -1)
- return 0;
- if (iod.irq > 0)
- dev->id_irq = 1 << iod.irq;
- if (IS_8251(iod.if_type)) {
+ if(pc98_check_if_type(dev->id_iobase, &iod) == -1)
+ return 0;
+ if(IS_8251(iod.if_type)){
+ if ( iod.irq > 0 )
+ dev->id_irq = (1 << iod.irq);
outb(iod.cmd, 0);
DELAY(10);
outb(iod.cmd, 0);
@@ -1044,20 +865,23 @@ sioprobe(dev)
if (( inb(iod.sts) & STS8251_TxEMP ) == 0 ) {
ret = 0;
}
- if (if_8251_type[iod.if_type & 0x0f].check_irq) {
- COM_INT_DISABLE
- tmp = ( inb( iod.ctrl ) & ~(IEN_Rx|IEN_TxEMP|IEN_Tx));
- outb( iod.ctrl, tmp|IEN_TxEMP );
- DELAY(10);
- ret = isa_irq_pending() ? 4 : 0;
- outb( iod.ctrl, tmp );
- COM_INT_ENABLE
- } else {
- /*
- * B98_01 doesn't activate TxEMP interrupt line
- * when being reset, so we can't check irq pending.
- */
- ret = 4;
+ switch (iod.if_type) {
+ case COM_IF_INTERNAL:
+ COM_INT_DISABLE
+ tmp = ( inb( iod.ctrl ) & ~(IEN_Rx|IEN_TxEMP|IEN_Tx));
+ outb( iod.ctrl, tmp|IEN_TxEMP );
+ DELAY(10);
+ ret = isa_irq_pending() ? 4 : 0;
+ outb( iod.ctrl, tmp );
+ COM_INT_ENABLE
+ break;
+#ifdef COM_IF_B98_01
+ case COM_IF_B98_01:
+ /* B98_01 doesn't activate TxEMP interrupt line
+ when being reset, so we can't check irq pending.*/
+ ret = 4;
+ break;
+#endif
}
if (epson_machine_id==0x20) { /* XXX */
ret = 4;
@@ -1075,22 +899,6 @@ sioprobe(dev)
*/
idev = dev;
mcr_image = MCR_IENABLE;
-#ifdef PC98
- if (iod.if_type == COM_IF_RSA98III) {
- mcr_image = 0;
- rsabase = idev->id_iobase & 0xfff0;
- if (rsabase != idev->id_iobase)
- return(0);
- outb(rsabase + rsa_msr, 0x04);
- outb(rsabase + rsa_frr, 0x00);
- if ((inb(rsabase + rsa_srr) & 0x36) != 0x36)
- return (0);
- outb(rsabase + rsa_ier, 0x00);
- outb(rsabase + rsa_frr, 0x00);
- outb(rsabase + rsa_tivsr, 0x00);
- outb(rsabase + rsa_tcr, 0x00);
- }
-#endif /* PC98 */
#ifdef COM_MULTIPORT
if (COM_ISMULTIPORT(dev)) {
idev = find_isadev(isa_devtab_tty, &siodriver,
@@ -1114,28 +922,18 @@ sioprobe(dev)
mcr_image = 0;
#ifdef PC98
- tmp = if_16550a_type[iod.if_type & 0x0f].irr_write;
- if (tmp != -1) {
- /* MC16550II */
- switch (idev->id_irq) {
- case IRQ3: irqout = 4; break;
- case IRQ5: irqout = 5; break;
- case IRQ6: irqout = 6; break;
- case IRQ12: irqout = 7; break;
- default:
- printf("sio%d: irq configuration error\n", dev->id_unit);
- return (0);
- }
- outb((dev->id_iobase & 0x00ff) | tmp, irqout);
+ switch(idev->id_irq){
+ case IRQ3: irqout = 4; break;
+ case IRQ5: irqout = 5; break;
+ case IRQ6: irqout = 6; break;
+ case IRQ12: irqout = 7; break;
+ default:
+ printf("sio%d: irq configuration error\n",dev->id_unit);
+ return (0);
}
- port_shift = if_16550a_type[iod.if_type & 0x0f].port_shift;
+ outb(dev->id_iobase+0x1000, irqout);
#endif
bzero(failures, sizeof failures);
-#ifdef PC98
- if (iod.if_type == COM_IF_RSA98III)
- iobase = dev->id_iobase + 8;
- else
-#endif
iobase = dev->id_iobase;
/*
@@ -1160,19 +958,10 @@ sioprobe(dev)
if (iobase == siocniobase)
DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
else {
-#ifdef PC98
- tmp = ttspeedtab(SIO_TEST_SPEED,
- if_16550a_type[iod.if_type & 0x0f].speedtab);
- outb(iobase + (com_cfcr << port_shift), CFCR_DLAB|CFCR_8BITS);
- outb(iobase + (com_dlbl << port_shift), tmp & 0xff);
- outb(iobase + (com_dlbh << port_shift), (tmp >> 8) & 0xff);
- outb(iobase + (com_cfcr << port_shift), CFCR_8BITS);
-#else
outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
outb(iobase + com_dlbl, COMBRD(SIO_TEST_SPEED) & 0xff);
outb(iobase + com_dlbh, (u_int) COMBRD(SIO_TEST_SPEED) >> 8);
outb(iobase + com_cfcr, CFCR_8BITS);
-#endif
DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10));
}
@@ -1182,13 +971,8 @@ sioprobe(dev)
* guarantee an edge trigger if an interrupt can be generated.
*/
/* EXTRA DELAY? */
-#ifdef PC98
- outb(iobase + (com_mcr << port_shift), mcr_image);
- outb(iobase + (com_ier << port_shift), 0);
-#else
outb(iobase + com_mcr, mcr_image);
outb(iobase + com_ier, 0);
-#endif
DELAY(1000); /* XXX */
irqmap[0] = isa_irq_pending();
@@ -1197,11 +981,7 @@ sioprobe(dev)
* without annoying any external device.
*/
/* EXTRA DELAY? */
-#ifdef PC98
- outb(iobase + (com_mcr << port_shift), mcr_image | MCR_LOOPBACK);
-#else
outb(iobase + com_mcr, mcr_image | MCR_LOOPBACK);
-#endif
/*
* Attempt to generate an output interrupt. On 8250's, setting
@@ -1211,14 +991,7 @@ sioprobe(dev)
* current setting. On 16550A's, setting IER_ETXRDY only
* generates an interrupt when IER_ETXRDY is not already set.
*/
-#ifdef PC98
- outb(iobase + (com_ier << port_shift), IER_ETXRDY);
- if (iod.if_type == COM_IF_RSA98III) {
- outb(rsabase + rsa_ier, 0x04);
- }
-#else
outb(iobase + com_ier, IER_ETXRDY);
-#endif /* PC98 */
/*
* On some 16x50 incompatibles, setting IER_ETXRDY doesn't generate
@@ -1226,11 +999,7 @@ sioprobe(dev)
* output. Loopback may be broken on the same incompatibles but
* it's unlikely to do more than allow the null byte out.
*/
-#ifdef PC98
- outb(iobase + (com_data << port_shift), 0);
-#else
outb(iobase + com_data, 0);
-#endif
DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10));
/*
@@ -1241,11 +1010,7 @@ sioprobe(dev)
* are disabled.
*/
/* EXTRA DELAY? */
-#ifdef PC98
- outb(iobase + (com_mcr << port_shift), mcr_image);
-#else
outb(iobase + com_mcr, mcr_image);
-#endif /* PC98 */
/*
* It's a definitly Serial PCMCIA(16550A), but still be required
@@ -1255,28 +1020,14 @@ sioprobe(dev)
/* Reading IIR register twice */
for ( fn = 0; fn < 2; fn ++ ) {
DELAY(10000);
-#ifdef PC98
- failures[6] = inb(iobase + (com_iir << port_shift));
-#else
failures[6] = inb(iobase + com_iir);
-#endif
}
/* Check IIR_TXRDY clear ? */
-#ifdef PC98
- result = if_16550a_type[iod.if_type & 0x0f].io_size;
-#else
result = IO_COMSIZE;
-#endif
if ( failures[6] & IIR_TXRDY ) {
/* Nop, Double check with clearing IER */
-#ifdef PC98
- outb(iobase + (com_ier << port_shift), 0);
- if (inb(iobase +
- (com_iir << port_shift)) & IIR_NOPEND) {
-#else
outb(iobase + com_ier, 0);
if ( inb(iobase + com_iir) & IIR_NOPEND ) {
-#endif
/* Ok. we're familia this gang */
dev->id_flags |= COM_C_IIR_TXRDYBUG; /* Set IIR_TXRDYBUG */
} else {
@@ -1287,11 +1038,7 @@ sioprobe(dev)
/* OK. this is well-known guys */
dev->id_flags &= ~COM_C_IIR_TXRDYBUG; /*Clear IIR_TXRDYBUG*/
}
-#ifdef PC98
- outb(iobase + (com_cfcr << port_shift), CFCR_8BITS);
-#else
outb(iobase + com_cfcr, CFCR_8BITS);
-#endif
enable_intr();
return (iobase == siocniobase ? IO_COMSIZE : result);
}
@@ -1305,37 +1052,15 @@ sioprobe(dev)
* o the interrupt goes away when the IIR in the UART is read.
*/
/* EXTRA DELAY? */
-#ifdef PC98
- failures[0] = inb(iobase + (com_cfcr << port_shift)) - CFCR_8BITS;
- failures[1] = inb(iobase + (com_ier << port_shift)) - IER_ETXRDY;
- failures[2] = inb(iobase + (com_mcr << port_shift)) - mcr_image;
-#else
failures[0] = inb(iobase + com_cfcr) - CFCR_8BITS;
failures[1] = inb(iobase + com_ier) - IER_ETXRDY;
failures[2] = inb(iobase + com_mcr) - mcr_image;
-#endif
DELAY(10000); /* Some internal modems need this time */
irqmap[1] = isa_irq_pending();
-#ifdef PC98
- failures[4] = (inb(iobase + (com_iir << port_shift)) & IIR_IMASK)
- - IIR_TXRDY;
- if (iod.if_type == COM_IF_RSA98III) {
- inb(rsabase + rsa_srr);
- }
-#else
failures[4] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_TXRDY;
-#endif
DELAY(1000); /* XXX */
irqmap[2] = isa_irq_pending();
-#ifdef PC98
- failures[6] = (inb(iobase + (com_iir << port_shift)) & IIR_IMASK)
- - IIR_NOPEND;
- if (iod.if_type == COM_IF_RSA98III) {
- inb(rsabase + rsa_srr);
- }
-#else
failures[6] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
-#endif
/*
* Turn off all device interrupts and check that they go off properly.
@@ -1346,30 +1071,12 @@ sioprobe(dev)
* (On the system that this was first tested on, the input floats high
* and gives a (masked) interrupt as soon as the gate is closed.)
*/
-#ifdef PC98
- outb(iobase + (com_ier << port_shift), 0);
- outb(iobase + (com_cfcr << port_shift), CFCR_8BITS);
- failures[7] = inb(iobase + (com_ier << port_shift));
- if (iod.if_type == COM_IF_RSA98III) {
- outb(rsabase + rsa_ier, 0x00);
- }
-#else
outb(iobase + com_ier, 0);
outb(iobase + com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */
failures[7] = inb(iobase + com_ier);
-#endif
DELAY(1000); /* XXX */
irqmap[3] = isa_irq_pending();
-#ifdef PC98
- failures[9] = (inb(iobase + (com_iir << port_shift)) & IIR_IMASK)
- - IIR_NOPEND;
- if (iod.if_type == COM_IF_RSA98III) {
- inb(rsabase + rsa_srr);
- outb(rsabase + rsa_frr, 0x00);
- }
-#else
failures[9] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
-#endif
enable_intr();
@@ -1382,18 +1089,10 @@ sioprobe(dev)
printf("sio%d: irq maps: %#x %#x %#x %#x\n",
dev->id_unit, irqmap[0], irqmap[1], irqmap[2], irqmap[3]);
-#ifdef PC98
- result = if_16550a_type[iod.if_type & 0x0f].io_size;
-#else
result = IO_COMSIZE;
-#endif
for (fn = 0; fn < sizeof failures; ++fn)
if (failures[fn]) {
-#ifdef PC98
- outb(iobase + (com_mcr << port_shift), 0);
-#else
outb(iobase + com_mcr, 0);
-#endif
result = 0;
if (bootverbose) {
printf("sio%d: probe failed test(s):",
@@ -1433,22 +1132,13 @@ espattach(isdp, com, esp_port)
*/
/* Get the dip-switch configuration */
-#ifdef PC98
- outb(esp_port + ESP98_CMD1, ESP_GETDIPS);
- dips = inb(esp_port + ESP98_STATUS1);
-#else
outb(esp_port + ESP_CMD1, ESP_GETDIPS);
dips = inb(esp_port + ESP_STATUS1);
-#endif
/*
* Bits 0,1 of dips say which COM port we are.
*/
-#ifdef PC98
- if ((com->iobase & 0xff) == likely_com_ports[dips & 0x03])
-#else
if (com->iobase == likely_com_ports[dips & 0x03])
-#endif
printf(" : ESP");
else {
printf(" esp_port has com %d\n", dips & 0x03);
@@ -1458,15 +1148,9 @@ espattach(isdp, com, esp_port)
/*
* Check for ESP version 2.0 or later: bits 4,5,6 = 010.
*/
-#ifdef PC98
- outb(esp_port + ESP98_CMD1, ESP_GETTEST);
- val = inb(esp_port + ESP98_STATUS1); /* clear reg 1 */
- val = inb(esp_port + ESP98_STATUS2);
-#else
outb(esp_port + ESP_CMD1, ESP_GETTEST);
val = inb(esp_port + ESP_STATUS1); /* clear reg 1 */
val = inb(esp_port + ESP_STATUS2);
-#endif
if ((val & 0x70) < 0x20) {
printf("-old (%o)", val & 0x70);
return (0);
@@ -1501,28 +1185,11 @@ sioattach(isdp)
Port_t iobase;
int s;
int unit;
-#ifdef PC98
- int port_shift = 0;
- u_long ibufsize;
-#endif
- isdp->id_ointr = siointr;
isdp->id_ri_flags |= RI_FAST;
-#ifdef PC98
- if (((isdp->id_flags >> 24) & 0xff) == COM_IF_RSA98III)
- iobase = isdp->id_iobase + 8;
- else
-#endif
iobase = isdp->id_iobase;
unit = isdp->id_unit;
-#ifndef PC98
com = malloc(sizeof *com, M_TTYS, M_NOWAIT);
-#else
- ibufsize = RS_IBUFSIZE;
- if (((isdp->id_flags >> 24) & 0xff) == COM_IF_RSA98III)
- ibufsize = 2048;
- com = malloc((sizeof *com) + ibufsize * 6, M_TTYS, M_NOWAIT);
-#endif
if (com == NULL)
return (0);
@@ -1539,14 +1206,6 @@ sioattach(isdp)
* device from sending before we are ready.
*/
bzero(com, sizeof *com);
-#ifdef PC98
- com->CE_INPUT_OFFSET = ibufsize;
- com->ibuf1 = (u_char *)com + (sizeof *com);
- com->ibuf2 = com->ibuf1 + (ibufsize * 2);
- com->obuf1 = com->ibuf2 + (ibufsize * 2);
- com->obuf2 = com->obuf1 + ibufsize;
- bzero(com->ibuf1, ibufsize * 6);
-#endif
com->unit = unit;
com->cfcr_image = CFCR_8BITS;
com->dtr_wait = 3 * hz;
@@ -1554,29 +1213,24 @@ sioattach(isdp)
com->no_irq = isdp->id_irq == 0;
com->tx_fifo_size = 1;
com->iptr = com->ibuf = com->ibuf1;
-#ifndef PC98
com->ibufend = com->ibuf1 + RS_IBUFSIZE;
com->ihighwater = com->ibuf1 + RS_IHIGHWATER;
-#else
- com->ibufend = com->ibuf1 + com->CE_INPUT_OFFSET;
- com->ihighwater = com->ibuf1 + (3 * com->CE_INPUT_OFFSET / 4);
-#endif
com->obufs[0].l_head = com->obuf1;
com->obufs[1].l_head = com->obuf2;
com->iobase = iobase;
#ifdef PC98
- if (pc98_set_ioport(com, isdp->id_flags) == -1) {
- com->pc98_if_type = (isdp->id_flags >> 24) & 0xff;
- port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift;
- com->data_port = iobase + (com_data << port_shift);
- com->int_id_port = iobase + (com_iir << port_shift);
- com->modem_ctl_port = iobase + (com_mcr << port_shift);
- com->mcr_image = inb(com->modem_ctl_port);
- com->line_status_port = iobase + (com_lsr << port_shift);
- com->modem_status_port = iobase + (com_msr << port_shift);
- com->intr_ctl_port = iobase + (com_ier << port_shift);
- }
+ if(pc98_set_ioport(com, iobase) == -1)
+ if((iobase & 0x0f0) == 0xd0) {
+ com->pc98_if_type = MC16550;
+ com->data_port = iobase + com_data;
+ com->int_id_port = iobase + com_iir;
+ com->modem_ctl_port = iobase + com_mcr;
+ com->mcr_image = inb(com->modem_ctl_port);
+ com->line_status_port = iobase + com_lsr;
+ com->modem_status_port = iobase + com_msr;
+ com->intr_ctl_port = iobase + com_ier;
+ }
#else /* not PC98 */
com->data_port = iobase + com_data;
com->int_id_port = iobase + com_iir;
@@ -1599,7 +1253,7 @@ sioattach(isdp)
com->it_in.c_lflag = 0;
if (unit == comconsole) {
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
DELAY(100000);
#endif
com->it_in.c_iflag = TTYDEF_IFLAG;
@@ -1618,6 +1272,12 @@ sioattach(isdp)
/* attempt to determine UART type */
printf("sio%d: type", unit);
+#ifdef DSI_SOFT_MODEM
+ if((inb(iobase+7) ^ inb(iobase+7)) & 0x80) {
+ printf(" Digicom Systems, Inc. SoftModem");
+ goto determined_type;
+ }
+#endif /* DSI_SOFT_MODEM */
#ifndef PC98
#ifdef COM_MULTIPORT
@@ -1643,17 +1303,35 @@ sioattach(isdp)
}
#endif /* !PC98 */
#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- com_int_TxRx_disable( com );
- com_cflag_and_speed_set( com, com->it_in.c_cflag, comdefaultrate );
- com_tiocm_bic( com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE );
- com_send_break_off( com );
- printf(" 8251%s", if_8251_type[com->pc98_if_type & 0x0f].name);
+ if(IS_8251(com->pc98_if_type)){
+ com_int_TxRx_disable( com );
+ com_cflag_and_speed_set( com, com->it_in.c_cflag,
+ comdefaultrate );
+ com_tiocm_bic( com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE );
+ com_send_break_off( com );
+ switch(com->pc98_if_type){
+ case COM_IF_INTERNAL:
+ printf(" 8251 (internal)");
+ break;
+#ifdef COM_IF_PC9861K
+ case COM_IF_PC9861K:
+ printf(" 8251 (PC9861K)");
+ break;
+#endif
+#ifdef COM_IF_PIO9032B
+ case COM_IF_PIO9032B:
+ printf(" 8251 (PIO9032B)");
+ break;
+#endif
+#ifdef COM_IF_B98_01
+ case COM_IF_B98_01:
+ printf(" 8251 (B98_01)");
+ break;
+#endif
+ }
} else {
- outb(iobase + (com_fifo << port_shift), FIFO_ENABLE | FIFO_RX_HIGH);
-#else
- outb(iobase + com_fifo, FIFO_ENABLE | FIFO_RX_HIGH);
#endif /* PC98 */
+ outb(iobase + com_fifo, FIFO_ENABLE | FIFO_RX_HIGH);
DELAY(100);
com->st16650a = 0;
switch (inb(com->int_id_port) & IIR_FIFO_MASK) {
@@ -1671,10 +1349,6 @@ sioattach(isdp)
printf(" 16550A fifo disabled");
} else {
com->hasfifo = TRUE;
-#ifdef PC98
- com->tx_fifo_size = 0; /* XXX flag conflicts. */
- printf(" 16550A");
-#else
if (COM_ST16650A(isdp)) {
com->st16650a = 1;
com->tx_fifo_size = 32;
@@ -1683,21 +1357,8 @@ sioattach(isdp)
com->tx_fifo_size = COM_FIFOSIZE(isdp);
printf(" 16550A");
}
-#endif
- }
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- com->tx_fifo_size = 2048;
- com->rsabase = isdp->id_iobase;
- outb(com->rsabase + rsa_ier, 0x00);
- outb(com->rsabase + rsa_frr, 0x00);
}
-#endif
-
#ifdef COM_ESP
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_ESP98)
-#endif
for (espp = likely_esp_ports; *espp != 0; espp++)
if (espattach(isdp, com, *espp)) {
com->tx_fifo_size = 1024;
@@ -1715,17 +1376,6 @@ sioattach(isdp)
break;
}
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSB3000) {
- /* Set RSB-2000/3000 Extended Buffer mode. */
- u_char lcr;
- lcr = inb(iobase + (com_cfcr << port_shift));
- outb(iobase + (com_cfcr << port_shift), lcr | CFCR_DLAB);
- outb(iobase + (com_emr << port_shift), EMR_EXBUFF | EMR_EFMODE);
- outb(iobase + (com_cfcr << port_shift), lcr);
- }
-#endif
-
#ifdef COM_ESP
if (com->esp) {
/*
@@ -1735,53 +1385,23 @@ sioattach(isdp)
* bursts of input.
* XXX flow control should be set in comparam(), not here.
*/
-#ifdef PC98
- outb(com->esp_port + ESP98_CMD1, ESP_SETMODE);
- outb(com->esp_port + ESP98_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO);
-#else
outb(com->esp_port + ESP_CMD1, ESP_SETMODE);
outb(com->esp_port + ESP_CMD2, ESP_MODE_RTS | ESP_MODE_FIFO);
-#endif
/* Set RTS/CTS flow control. */
-#ifdef PC98
- outb(com->esp_port + ESP98_CMD1, ESP_SETFLOWTYPE);
- outb(com->esp_port + ESP98_CMD2, ESP_FLOW_RTS);
- outb(com->esp_port + ESP98_CMD2, ESP_FLOW_CTS);
-#else
outb(com->esp_port + ESP_CMD1, ESP_SETFLOWTYPE);
outb(com->esp_port + ESP_CMD2, ESP_FLOW_RTS);
outb(com->esp_port + ESP_CMD2, ESP_FLOW_CTS);
-#endif
/* Set flow-control levels. */
-#ifdef PC98
- outb(com->esp_port + ESP98_CMD1, ESP_SETRXFLOW);
- outb(com->esp_port + ESP98_CMD2, HIBYTE(768));
- outb(com->esp_port + ESP98_CMD2, LOBYTE(768));
- outb(com->esp_port + ESP98_CMD2, HIBYTE(512));
- outb(com->esp_port + ESP98_CMD2, LOBYTE(512));
-#else
outb(com->esp_port + ESP_CMD1, ESP_SETRXFLOW);
outb(com->esp_port + ESP_CMD2, HIBYTE(768));
outb(com->esp_port + ESP_CMD2, LOBYTE(768));
outb(com->esp_port + ESP_CMD2, HIBYTE(512));
outb(com->esp_port + ESP_CMD2, LOBYTE(512));
-#endif
-
-#ifdef PC98
- /* Set UART clock prescaler. */
- outb(com->esp_port + ESP98_CMD1, ESP_SETCLOCK);
- outb(com->esp_port + ESP98_CMD2, 2); /* 4 times */
-#endif
}
#endif /* COM_ESP */
-#ifdef PC98
- printf("%s", if_16550a_type[com->pc98_if_type & 0x0f].name);
- outb(iobase + (com_fifo << port_shift), 0);
-#else
outb(iobase + com_fifo, 0);
-#endif
determined_type: ;
#ifdef COM_MULTIPORT
@@ -1793,7 +1413,7 @@ determined_type: ;
printf(")");
com->no_irq = find_isadev(isa_devtab_tty, &siodriver,
COM_MPMASTER(isdp))->id_irq == 0;
- }
+ }
#endif /* COM_MULTIPORT */
#ifdef PC98
}
@@ -1852,9 +1472,6 @@ sioopen(dev, flag, mode, p)
int s;
struct tty *tp;
int unit;
-#ifdef PC98
- int port_shift = 0;
-#endif
mynor = minor(dev);
unit = MINOR_TO_UNIT(mynor);
@@ -1870,11 +1487,6 @@ sioopen(dev, flag, mode, p)
tp = com->tp = &sio_tty[unit];
#endif
s = spltty();
-
-#ifdef PC98
- if (!IS_8251(com->pc98_if_type))
- port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift;
-#endif
/*
* We jump to this label after all non-interrupted sleeps to pick
* up any changes of the device state.
@@ -1928,15 +1540,11 @@ open_top:
tp->t_dev = dev;
tp->t_termios = mynor & CALLOUT_MASK
? com->it_out : com->it_in;
-#ifndef PC98
tp->t_ififosize = 2 * RS_IBUFSIZE;
-#else
- tp->t_ififosize = 2 * com->CE_INPUT_OFFSET;
-#endif
tp->t_ispeedwat = (speed_t)-1;
tp->t_ospeedwat = (speed_t)-1;
#ifdef PC98
- if (!IS_8251(com->pc98_if_type))
+ if(!IS_8251(com->pc98_if_type))
#endif
(void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
com->poll = com->no_irq;
@@ -1947,7 +1555,7 @@ open_top:
if (error != 0)
goto out;
#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
+ if(IS_8251(com->pc98_if_type)){
com_tiocm_bis(com, TIOCM_DTR|TIOCM_RTS);
pc98_msrint_start(dev);
}
@@ -1969,17 +1577,9 @@ open_top:
* input.
*/
while (TRUE) {
-#ifdef PC98
- outb(iobase + (com_fifo << port_shift),
- FIFO_RCV_RST | FIFO_XMT_RST
- | com->fifo_image);
- if (com->pc98_if_type == COM_IF_RSA98III)
- outb(com->rsabase + rsa_frr , 0x00);
-#else
outb(iobase + com_fifo,
FIFO_RCV_RST | FIFO_XMT_RST
| com->fifo_image);
-#endif
/*
* XXX the delays are for superstitious
* historical reasons. It must be less than
@@ -1992,19 +1592,9 @@ open_top:
* for about 85 usec instead of 100.
*/
DELAY(50);
-#ifndef PC98
if (!(inb(com->line_status_port) & LSR_RXRDY))
-#else
- if (com->pc98_if_type == COM_IF_RSA98III
- ? !(inb(com->rsabase + rsa_srr) & 0x08)
- : !(inb(com->line_status_port) & LSR_RXRDY))
-#endif
break;
-#ifdef PC98
- outb(iobase + (com_fifo << port_shift), 0);
-#else
outb(iobase + com_fifo, 0);
-#endif
DELAY(50);
(void) inb(com->data_port);
}
@@ -2012,10 +1602,11 @@ open_top:
disable_intr();
#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- com_tiocm_bis(com, TIOCM_LE);
- com->pc98_prev_modem_status = pc98_get_modem_status(com);
- com_int_Rx_enable(com);
+ if(IS_8251(com->pc98_if_type)){
+ com_tiocm_bis(com, TIOCM_LE);
+ com->pc98_prev_modem_status =
+ pc98_get_modem_status(com);
+ com_int_Rx_enable(com);
} else {
#endif
(void) inb(com->line_status_port);
@@ -2030,12 +1621,6 @@ open_top:
| IER_ERLS | IER_EMSC);
}
#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- outb(com->rsabase + rsa_ier, 0x1d);
- outb(com->intr_ctl_port, IER_ERLS | IER_EMSC);
- }
-#endif
-#ifdef PC98
}
#endif
enable_intr();
@@ -2137,9 +1722,6 @@ comhardclose(com)
int s;
struct tty *tp;
int unit;
-#ifdef PC98
- int port_shift = 0;
-#endif
unit = com->unit;
iobase = com->iobase;
@@ -2149,32 +1731,22 @@ comhardclose(com)
com->do_timestamp = FALSE;
com->do_dcd_timestamp = FALSE;
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- com_send_break_off(com);
- else {
- port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift;
- outb(iobase + (com_cfcr << port_shift),
- com->cfcr_image &= ~CFCR_SBREAK);
- }
-#else
- outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
+ if(IS_8251(com->pc98_if_type))
+ com_send_break_off(com);
+ else
#endif
+ outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
{
#ifdef PC98
int tmp;
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
com_int_TxRx_disable(com);
else
- outb(iobase + (com_ier << port_shift), 0);
- if (com->pc98_if_type == COM_IF_RSA98III) {
- outb(com->rsabase + rsa_ier, 0x00);
- }
-#else
- outb(iobase + com_ier, 0);
#endif
+ outb(iobase + com_ier, 0);
tp = com->tp;
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
tmp = pc98_get_modem_status(com) & TIOCM_CAR;
else
tmp = com->prev_modem_status & MSR_DCD;
@@ -2196,8 +1768,8 @@ comhardclose(com)
&& !(com->it_in.c_cflag & CLOCAL)
|| !(tp->t_state & TS_ISOPEN)) {
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- com_tiocm_bic(com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE);
+ if(IS_8251(com->pc98_if_type))
+ com_tiocm_bic(com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE);
else
#endif
(void)commctl(com, TIOCM_DTR, DMBIC);
@@ -2208,7 +1780,7 @@ comhardclose(com)
}
#ifdef PC98
else {
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
com_tiocm_bic(com, TIOCM_LE );
}
#endif
@@ -2219,11 +1791,7 @@ comhardclose(com)
* reboots. Some BIOSes fail to detect 16550s when the
* fifos are enabled.
*/
-#ifdef PC98
- outb(iobase + (com_fifo << port_shift), 0);
-#else
outb(iobase + com_fifo, 0);
-#endif
}
com->active_out = FALSE;
wakeup(&com->active_out);
@@ -2329,7 +1897,7 @@ siodtrwakeup(chan)
wakeup(&com->dtr_wait);
}
-static void
+void
siointr(unit)
int unit;
{
@@ -2340,9 +1908,6 @@ siointr(unit)
#else /* COM_MULTIPORT */
struct com_s *com;
bool_t possibly_more_intrs;
-#ifdef PC98
- u_char rsa_buf_status;
-#endif
/*
* Loop until there is no activity on any port. This is necessary
@@ -2367,20 +1932,6 @@ siointr(unit)
siointr1(com);
} else
#endif /* PC98 */
-#ifdef PC98
- if (com != NULL
- && !com->gone
- && com->pc98_if_type == COM_IF_RSA98III) {
- rsa_buf_status = inb(com->rsabase + rsa_srr) & 0xc9;
- if ((rsa_buf_status & 0xc8)
- || !(rsa_buf_status & 0x01)) {
- siointr1(com);
- if(rsa_buf_status
- != (inb(com->rsabase + rsa_srr) & 0xc9))
- possibly_more_intrs = TRUE;
- }
- } else
-#endif
if (com != NULL
&& !com->gone
&& (inb(com->int_id_port) & IIR_IMASK)
@@ -2403,14 +1954,13 @@ siointr1(com)
u_char modem_status;
u_char *ioptr;
u_char recv_data;
+ u_char int_ident;
u_char int_ctl;
u_char int_ctl_new;
#ifdef PC98
u_char tmp=0;
- u_char rsa_buf_status = 0;
- int rsa_tx_fifo_size=0;
- recv_data=0;
+recv_data=0;
#endif /* PC98 */
int_ctl = inb(com->intr_ctl_port);
@@ -2433,38 +1983,19 @@ more_intr:
} else
#endif /* PC98 */
line_status = inb(com->line_status_port);
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III)
- rsa_buf_status = inb(com->rsabase + rsa_srr);
-#endif /* PC98 */
/* input event? (check first to help avoid overruns) */
-#ifndef PC98
while (line_status & LSR_RCV_MASK) {
-#else
- while ((line_status & LSR_RCV_MASK)
- || (com->pc98_if_type == COM_IF_RSA98III
- && (rsa_buf_status & 0x08))) {
-#endif /* PC98 */
/* break/unnattached error bits or real input? */
#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
+ if(IS_8251(com->pc98_if_type)){
recv_data = inb(com->data_port);
- if (tmp & 0x78) {
+ if(tmp & 0x78){
pc98_i8251_or_cmd(com,CMD8251_ER);
recv_data = 0;
}
} else {
#endif /* PC98 */
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- if (!(rsa_buf_status & 0x08))
- recv_data = 0;
- else {
- recv_data = inb(com->data_port);
- }
- } else
-#endif
if (!(line_status & LSR_RXRDY))
recv_data = 0;
else
@@ -2521,16 +2052,12 @@ if (com->iptr - com->ibuf == 8)
setsofttty();
#endif
ioptr[0] = recv_data;
-#ifdef PC98
- ioptr[com->CE_INPUT_OFFSET] = line_status;
-#else
ioptr[CE_INPUT_OFFSET] = line_status;
-#endif
com->iptr = ++ioptr;
if (ioptr == com->ihighwater
&& com->state & CS_RTS_IFLOW)
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
com_tiocm_bic(com, TIOCM_RTS);
else
#endif
@@ -2545,20 +2072,16 @@ cont:
* jump from the top of the loop to here
*/
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
goto status_read;
else
#endif
line_status = inb(com->line_status_port) & 0x7F;
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III)
- rsa_buf_status = inb(com->rsabase + rsa_srr);
-#endif /* PC98 */
}
/* modem status change? (always check before doing output) */
#ifdef PC98
- if (!IS_8251(com->pc98_if_type)) {
+ if(!IS_8251(com->pc98_if_type)){
#endif
modem_status = inb(com->modem_status_port);
if (modem_status != com->last_modem_status) {
@@ -2593,30 +2116,13 @@ cont:
#endif
/* output queued and everything ready? */
-#ifndef PC98
if (line_status & LSR_TXRDY
&& com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
-#else
- if (((com->pc98_if_type == COM_IF_RSA98III)
- ? (rsa_buf_status & 0x02)
- : (line_status & LSR_TXRDY))
- && com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
-#endif
ioptr = com->obufq.l_head;
if (com->tx_fifo_size > 1) {
u_int ocount;
ocount = com->obufq.l_tail - ioptr;
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- rsa_buf_status = inb(com->rsabase + rsa_srr);
- rsa_tx_fifo_size = 1024;
- if (!(rsa_buf_status & 0x01))
- rsa_tx_fifo_size = 2048;
- if (ocount > rsa_tx_fifo_size)
- ocount = rsa_tx_fifo_size;
- } else
-#endif
if (ocount > com->tx_fifo_size)
ocount = com->tx_fifo_size;
com->bytes_out += ocount;
@@ -2628,8 +2134,8 @@ cont:
++com->bytes_out;
}
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- if (!(pc98_check_i8251_interrupt(com) & IEN_TxFLAG))
+ if(IS_8251(com->pc98_if_type))
+ if ( !(pc98_check_i8251_interrupt(com) & IEN_TxFLAG) )
com_int_Tx_enable(com);
#endif
com->obufq.l_head = ioptr;
@@ -2653,9 +2159,9 @@ cont:
}
com->state &= ~CS_BUSY;
#if defined(PC98)
- if (IS_8251(com->pc98_if_type))
- if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
- com_int_Tx_disable(com);
+ if(IS_8251(com->pc98_if_type))
+ if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
+ com_int_Tx_disable(com);
#endif
}
if (!(com->state & CS_ODONE)) {
@@ -2665,29 +2171,24 @@ cont:
}
}
if ( COM_IIR_TXRDYBUG(com) && (int_ctl != int_ctl_new)) {
- if (com->pc98_if_type == COM_IF_RSA98III) {
- int_ctl_new &= ~(IER_ETXRDY | IER_ERXRDY);
- outb(com->intr_ctl_port, int_ctl_new);
- outb(com->rsabase + rsa_ier, 0x1d);
- } else
outb(com->intr_ctl_port, int_ctl_new);
}
}
#ifdef PC98
else if (line_status & LSR_TXRDY) {
- if (IS_8251(com->pc98_if_type))
- if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
- com_int_Tx_disable(com);
+ if(IS_8251(com->pc98_if_type))
+ if ( pc98_check_i8251_interrupt(com) & IEN_TxFLAG )
+ com_int_Tx_disable(com);
}
- if (IS_8251(com->pc98_if_type))
- if ((tmp = inb(com->sts_port)) & STS8251_RxRDY)
- goto more_intr;
+ if(IS_8251(com->pc98_if_type))
+ if ((tmp = inb(com->sts_port)) & STS8251_RxRDY)
+ goto more_intr;
#endif
/* finished? */
#ifndef COM_MULTIPORT
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
return;
#endif
if ((inb(com->int_id_port) & IIR_IMASK) == IIR_NOPEND)
@@ -2749,6 +2250,34 @@ sioioctl(dev, cmd, data, flag, p)
case TIOCGWINSZ:
bzero(data, sizeof(struct winsize));
return (0);
+#ifdef DSI_SOFT_MODEM
+ /*
+ * Download micro-code to Digicom modem.
+ */
+ case TIOCDSIMICROCODE:
+ {
+ u_long l;
+ u_char *p,*pi;
+
+ pi = (u_char*)(*(caddr_t*)data);
+ error = copyin(pi,&l,sizeof l);
+ if(error)
+ {return error;};
+ pi += sizeof l;
+
+ p = malloc(l,M_TEMP,M_NOWAIT);
+ if(!p)
+ {return ENOBUFS;}
+ error = copyin(pi,p,l);
+ if(error)
+ {free(p,M_TEMP); return error;};
+ if(error = LoadSoftModem(
+ MINOR_TO_UNIT(mynor),iobase,l,p))
+ {free(p,M_TEMP); return error;}
+ free(p,M_TEMP);
+ return(0);
+ }
+#endif /* DSI_SOFT_MODEM */
default:
return (ENOTTY);
}
@@ -2796,7 +2325,7 @@ sioioctl(dev, cmd, data, flag, p)
return (error);
}
#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
+ if(IS_8251(com->pc98_if_type)){
switch (cmd) {
case TIOCSBRK:
com_send_break_on( com );
@@ -2851,25 +2380,13 @@ sioioctl(dev, cmd, data, flag, p)
return (ENOTTY);
}
} else {
- int port_shift;
- port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift;
#endif
switch (cmd) {
case TIOCSBRK:
-#ifdef PC98
- outb(iobase + (com_cfcr << port_shift),
- com->cfcr_image |= CFCR_SBREAK);
-#else
outb(iobase + com_cfcr, com->cfcr_image |= CFCR_SBREAK);
-#endif
break;
case TIOCCBRK:
-#ifdef PC98
- outb(iobase + (com_cfcr << port_shift),
- com->cfcr_image &= ~CFCR_SBREAK);
-#else
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
-#endif
break;
case TIOCSDTR:
(void)commctl(com, TIOCM_DTR, DMBIS);
@@ -2976,13 +2493,8 @@ repeat:
ibuf = com->ibuf2;
else
ibuf = com->ibuf1;
-#ifndef PC98
com->ibufend = ibuf + RS_IBUFSIZE;
com->ihighwater = ibuf + RS_IHIGHWATER;
-#else
- com->ibufend = ibuf + com->CE_INPUT_OFFSET;
- com->ihighwater = ibuf + (3 * com->CE_INPUT_OFFSET / 4);
-#endif
com->iptr = ibuf;
/*
@@ -2991,7 +2503,7 @@ repeat:
* there is room in the high-level buffer.
*/
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
tmp = com_tiocm_get(com) & TIOCM_RTS;
else
tmp = com->mcr_image & MCR_RTS;
@@ -3004,7 +2516,7 @@ repeat:
#endif
&& !(tp->t_state & TS_TBLOCK))
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
com_tiocm_bis(com, TIOCM_RTS);
else
#endif
@@ -3018,7 +2530,7 @@ repeat:
u_char delta_modem_status;
#ifdef PC98
- if (!IS_8251(com->pc98_if_type)) {
+ if(!IS_8251(com->pc98_if_type)){
#endif
disable_intr();
delta_modem_status = com->last_modem_status
@@ -3080,11 +2592,7 @@ repeat:
u_char line_status;
int recv_data;
-#ifndef PC98
line_status = (u_char) buf[CE_INPUT_OFFSET];
-#else
- line_status = (u_char) buf[com->CE_INPUT_OFFSET];
-#endif
recv_data = (u_char) *buf++;
if (line_status
& (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) {
@@ -3118,14 +2626,14 @@ comparam(tp, t)
int divisor;
u_char dlbh;
u_char dlbl;
+ int error;
Port_t iobase;
int s;
int unit;
+ int txtimeout;
#ifdef PC98
Port_t tmp_port;
int tmp_flg;
- int port_shift = 0;
- u_char param = 0;
#endif
#ifdef PC98
@@ -3133,27 +2641,16 @@ comparam(tp, t)
unit = DEV_TO_UNIT(tp->t_dev);
com = com_addr(unit);
iobase = com->iobase;
- if (IS_8251(com->pc98_if_type)) {
- divisor = pc98_ttspeedtab(com, t->c_ospeed);
- } else {
- port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift;
-
- /* do historical conversions */
- if (t->c_ispeed == 0)
- t->c_ispeed = t->c_ospeed;
-
- /* check requested parameters */
- divisor = ttspeedtab(t->c_ospeed,
- if_16550a_type[com->pc98_if_type & 0x0f].speedtab);
- }
-#else
+ if(IS_8251(com->pc98_if_type)) {
+ divisor = pc98_ttspeedtab(com, t->c_ospeed);
+ } else
+#endif
/* do historical conversions */
if (t->c_ispeed == 0)
t->c_ispeed = t->c_ospeed;
/* check requested parameters */
divisor = ttspeedtab(t->c_ospeed, comspeedtab);
-#endif
if (divisor < 0 || divisor > 0 && t->c_ispeed != t->c_ospeed)
return (EINVAL);
@@ -3165,8 +2662,8 @@ comparam(tp, t)
#endif
s = spltty();
#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
- if (divisor == 0)
+ if(IS_8251(com->pc98_if_type)){
+ if(divisor == 0)
com_tiocm_bic( com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE );
else
com_tiocm_bis( com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE );
@@ -3181,7 +2678,7 @@ comparam(tp, t)
#endif
cflag = t->c_cflag;
#ifdef PC98
- if (!IS_8251(com->pc98_if_type)) {
+ if(!IS_8251(com->pc98_if_type)){
#endif
switch (cflag & CSIZE) {
case CS5:
@@ -3225,29 +2722,80 @@ comparam(tp, t)
if (com->esp)
com->fifo_image |= FIFO_DMA_MODE;
#endif
-#ifdef PC98
- outb(iobase + (com_fifo << port_shift), com->fifo_image);
-#else
outb(iobase + com_fifo, com->fifo_image);
-#endif
}
+
+ /*
+ * Some UARTs lock up if the divisor latch registers are selected
+ * while the UART is doing output (they refuse to transmit anything
+ * more until given a hard reset). Fix this by stopping filling
+ * the device buffers and waiting for them to drain. Reading the
+ * line status port outside of siointr1() might lose some receiver
+ * error bits, but that is acceptable here.
+ */
#ifdef PC98
}
#endif
+ disable_intr();
+retry:
+ com->state &= ~CS_TTGO;
+ txtimeout = tp->t_timeout;
+ enable_intr();
+#ifdef PC98
+ if(IS_8251(com->pc98_if_type)){
+ tmp_port = com->sts_port;
+ tmp_flg = (STS8251_TxRDY|STS8251_TxEMP);
+ } else {
+ tmp_port = com->line_status_port;
+ tmp_flg = (LSR_TSRE|LSR_TXRDY);
+ }
+ while ((inb(tmp_port) & tmp_flg) != tmp_flg) {
+#else
+ while ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
+ != (LSR_TSRE | LSR_TXRDY)) {
+#endif
+ tp->t_state |= TS_SO_OCOMPLETE;
+ error = ttysleep(tp, TSA_OCOMPLETE(tp), TTIPRI | PCATCH,
+ "siotx", hz / 100);
+ if ( txtimeout != 0
+ && (!error || error == EAGAIN)
+ && (txtimeout -= hz / 100) <= 0
+ )
+ error = EIO;
+ if (com->gone)
+ error = ENODEV;
+ if (error != 0 && error != EAGAIN) {
+ if (!(tp->t_state & TS_TTSTOP)) {
+ disable_intr();
+ com->state |= CS_TTGO;
+ enable_intr();
+ }
+ splx(s);
+ return (error);
+ }
+ }
- disable_intr(); /* very important while com_data is hidden */
+ disable_intr(); /* very important while com_data is hidden */
+ /*
+ * XXX - clearing CS_TTGO is not sufficient to stop further output,
+ * because siopoll() calls comstart() which usually sets it again
+ * because TS_TTSTOP is clear. Setting TS_TTSTOP would not be
+ * sufficient, for similar reasons.
+ */
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- com_cflag_and_speed_set(com, cflag, t->c_ospeed);
- else {
+ if ((inb(tmp_port) & tmp_flg) != tmp_flg)
+#else
+ if ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY))
+ != (LSR_TSRE | LSR_TXRDY))
#endif
- if (divisor != 0) {
+ goto retry;
+
#ifdef PC98
- outb(iobase + (com_cfcr << port_shift), cfcr | CFCR_DLAB);
-#else
- outb(iobase + com_cfcr, cfcr | CFCR_DLAB);
+ if(!IS_8251(com->pc98_if_type)){
#endif
+ if (divisor != 0) {
+ outb(iobase + com_cfcr, cfcr | CFCR_DLAB);
/*
* Only set the divisor registers if they would change,
* since on some 16550 incompatibles (UMC8669F), setting
@@ -3255,29 +2803,20 @@ comparam(tp, t)
* data stops arriving.
*/
dlbl = divisor & 0xFF;
-#ifdef PC98
- if (inb(iobase + (com_dlbl << port_shift)) != dlbl)
- outb(iobase + (com_dlbl << port_shift), dlbl);
- dlbh = (u_int) divisor >> 8;
- if (inb(iobase + (com_dlbh << port_shift)) != dlbh)
- outb(iobase + (com_dlbh << port_shift), dlbh);
-#else
if (inb(iobase + com_dlbl) != dlbl)
outb(iobase + com_dlbl, dlbl);
dlbh = (u_int) divisor >> 8;
if (inb(iobase + com_dlbh) != dlbh)
outb(iobase + com_dlbh, dlbh);
-#endif
}
-#ifdef PC98
- }
- outb(iobase + (com_cfcr << port_shift), com->cfcr_image = cfcr);
-#else
outb(iobase + com_cfcr, com->cfcr_image = cfcr);
-#endif
+#ifdef PC98
+ } else
+ com_cflag_and_speed_set(com, cflag, t->c_ospeed);
+#endif
if (!(tp->t_state & TS_TTSTOP))
com->state |= CS_TTGO;
@@ -3300,7 +2839,7 @@ comparam(tp, t)
* on here, since comstart() won't do it later.
*/
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
com_tiocm_bis(com, TIOCM_RTS);
else
#endif
@@ -3319,26 +2858,14 @@ comparam(tp, t)
*/
com->state |= CS_ODEVREADY;
com->state &= ~CS_CTS_OFLOW;
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- param = inb(com->rsabase + rsa_msr);
- outb(com->rsabase + rsa_msr, param & 0x14);
- }
-#endif
if (cflag & CCTS_OFLOW) {
com->state |= CS_CTS_OFLOW;
#ifdef PC98
- if (IS_8251(com->pc98_if_type)) {
+ if(IS_8251(com->pc98_if_type)){
if (!(pc98_get_modem_status(com) & TIOCM_CTS))
com->state &= ~CS_ODEVREADY;
} else {
#endif
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- /* Set automatic flow control mode */
- outb(com->rsabase + rsa_msr, param | 0x08);
- } else
-#endif
if (!(com->last_modem_status & MSR_CTS))
com->state &= ~CS_ODEVREADY;
if (com->st16650a) {
@@ -3356,11 +2883,7 @@ comparam(tp, t)
}
-#ifdef PC98
- outb(iobase + (com_cfcr << port_shift), com->cfcr_image);
-#else
outb(iobase + com_cfcr, com->cfcr_image);
-#endif
/* XXX shouldn't call functions while intrs are disabled. */
@@ -3400,7 +2923,7 @@ comstart(tp)
com->state |= CS_TTGO;
if (tp->t_state & TS_TBLOCK) {
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
tmp = com_tiocm_get(com) & TIOCM_RTS;
else
tmp = com->mcr_image & MCR_RTS;
@@ -3409,14 +2932,14 @@ comstart(tp)
if (com->mcr_image & MCR_RTS && com->state & CS_RTS_IFLOW)
#endif
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
com_tiocm_bic(com, TIOCM_RTS);
else
#endif
outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
} else {
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
tmp = com_tiocm_get(com) & TIOCM_RTS;
else
tmp = com->mcr_image & MCR_RTS;
@@ -3427,7 +2950,7 @@ comstart(tp)
&& com->state & CS_RTS_IFLOW)
#endif
#ifdef PC98
- if (IS_8251(com->pc98_if_type))
+ if(IS_8251(com->pc98_if_type))
com_tiocm_bis(com, TIOCM_RTS);
else
#endif
@@ -3450,11 +2973,7 @@ comstart(tp)
if (!com->obufs[0].l_queued) {
com->obufs[0].l_tail
= com->obuf1 + q_to_b(&tp->t_outq, com->obuf1,
-#ifndef PC98
sizeof com->obuf1);
-#else
- com->CE_INPUT_OFFSET);
-#endif
com->obufs[0].l_next = NULL;
com->obufs[0].l_queued = TRUE;
disable_intr();
@@ -3474,11 +2993,7 @@ comstart(tp)
if (tp->t_outq.c_cc != 0 && !com->obufs[1].l_queued) {
com->obufs[1].l_tail
= com->obuf2 + q_to_b(&tp->t_outq, com->obuf2,
-#ifndef PC98
sizeof com->obuf2);
-#else
- com->CE_INPUT_OFFSET);
-#endif
com->obufs[1].l_next = NULL;
com->obufs[1].l_queued = TRUE;
disable_intr();
@@ -3515,18 +3030,10 @@ siostop(tp, rw)
int rw;
{
struct com_s *com;
-#ifdef PC98
- int port_shift = 0;
- int rsa98_tmp = 0;
-#endif
com = com_addr(DEV_TO_UNIT(tp->t_dev));
if (com->gone)
return;
-#ifdef PC98
- if (IS_8251(com->pc98_if_type))
- port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift;
-#endif
disable_intr();
if (rw & FWRITE) {
if (com->hasfifo)
@@ -3534,17 +3041,9 @@ siostop(tp, rw)
/* XXX avoid h/w bug. */
if (!com->esp)
#endif
-#ifdef PC98
- outb(com->iobase + (com_fifo << port_shift),
- FIFO_XMT_RST | com->fifo_image);
- if (com->pc98_if_type == COM_IF_RSA98III)
- for(rsa98_tmp = 0; rsa98_tmp < 2048; rsa98_tmp++)
- outb(com->iobase + (com_fifo << port_shift),
- FIFO_XMT_RST | com->fifo_image);
-#else
+ /* XXX does this flush everything? */
outb(com->iobase + com_fifo,
FIFO_XMT_RST | com->fifo_image);
-#endif
com->obufs[0].l_queued = FALSE;
com->obufs[1].l_queued = FALSE;
if (com->state & CS_ODONE)
@@ -3558,17 +3057,9 @@ siostop(tp, rw)
/* XXX avoid h/w bug. */
if (!com->esp)
#endif
-#ifdef PC98
- if (com->pc98_if_type == COM_IF_RSA98III) {
- for(rsa98_tmp = 0; rsa98_tmp < 2048; rsa98_tmp++)
- inb(com->data_port);
- }
- outb(com->iobase + (com_fifo << port_shift),
- FIFO_RCV_RST | com->fifo_image);
-#else
+ /* XXX does this flush everything? */
outb(com->iobase + com_fifo,
FIFO_RCV_RST | com->fifo_image);
-#endif
com_events -= (com->iptr - com->ibuf);
com->iptr = com->ibuf;
}
@@ -3815,18 +3306,6 @@ static void siocnclose __P((struct siocnstate *sp));
static void siocnopen __P((struct siocnstate *sp));
static void siocntxwait __P((void));
-/*
- * XXX: sciocnget() and sciocnputc() are not declared static, as they are
- * referred to from i386/i386/i386-gdbstub.c.
- */
-static cn_probe_t siocnprobe;
-static cn_init_t siocninit;
-static cn_checkc_t siocncheckc;
- cn_getc_t siocngetc;
- cn_putc_t siocnputc;
-
-CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
-
static void
siocntxwait()
{
@@ -3948,7 +3427,7 @@ siocnclose(sp)
outb(iobase + com_ier, sp->ier);
}
-static void
+void
siocnprobe(cp)
struct consdev *cp;
{
@@ -4014,14 +3493,14 @@ siocnprobe(cp)
}
}
-static void
+void
siocninit(cp)
struct consdev *cp;
{
comconsole = DEV_TO_UNIT(cp->cn_dev);
}
-static int
+int
siocncheckc(dev)
dev_t dev;
{
@@ -4079,6 +3558,126 @@ siocnputc(dev, c)
splx(s);
}
+#ifdef DSI_SOFT_MODEM
+/*
+ * The magic code to download microcode to a "Connection 14.4+Fax"
+ * modem from Digicom Systems Inc. Very magic.
+ */
+
+#define DSI_ERROR(str) { ptr = str; goto error; }
+static int
+LoadSoftModem(int unit, int base_io, u_long size, u_char *ptr)
+{
+ int int_c,int_k;
+ int data_0188, data_0187;
+
+ /*
+ * First see if it is a DSI SoftModem
+ */
+ if(!((inb(base_io+7) ^ inb(base_io+7)) & 0x80))
+ return ENODEV;
+
+ data_0188 = inb(base_io+4);
+ data_0187 = inb(base_io+3);
+ outb(base_io+3,0x80);
+ outb(base_io+4,0x0C);
+ outb(base_io+0,0x31);
+ outb(base_io+1,0x8C);
+ outb(base_io+7,0x10);
+ outb(base_io+7,0x19);
+
+ if(0x18 != (inb(base_io+7) & 0x1A))
+ DSI_ERROR("dsp bus not granted");
+
+ if(0x01 != (inb(base_io+7) & 0x01)) {
+ outb(base_io+7,0x18);
+ outb(base_io+7,0x19);
+ if(0x01 != (inb(base_io+7) & 0x01))
+ DSI_ERROR("program mem not granted");
+ }
+
+ int_c = 0;
+
+ while(1) {
+ if(int_c >= 7 || size <= 0x1800)
+ break;
+
+ for(int_k = 0 ; int_k < 0x800; int_k++) {
+ outb(base_io+0,*ptr++);
+ outb(base_io+1,*ptr++);
+ outb(base_io+2,*ptr++);
+ }
+
+ size -= 0x1800;
+ int_c++;
+ }
+
+ if(size > 0x1800) {
+ outb(base_io+7,0x18);
+ outb(base_io+7,0x19);
+ if(0x00 != (inb(base_io+7) & 0x01))
+ DSI_ERROR("program data not granted");
+
+ for(int_k = 0 ; int_k < 0x800; int_k++) {
+ outb(base_io+1,*ptr++);
+ outb(base_io+2,0);
+ outb(base_io+1,*ptr++);
+ outb(base_io+2,*ptr++);
+ }
+
+ size -= 0x1800;
+
+ while(size > 0x1800) {
+ for(int_k = 0 ; int_k < 0xC00; int_k++) {
+ outb(base_io+1,*ptr++);
+ outb(base_io+2,*ptr++);
+ }
+ size -= 0x1800;
+ }
+
+ if(size < 0x1800) {
+ for(int_k=0;int_k<size/2;int_k++) {
+ outb(base_io+1,*ptr++);
+ outb(base_io+2,*ptr++);
+ }
+ }
+
+ } else if (size > 0) {
+ if(int_c == 7) {
+ outb(base_io+7,0x18);
+ outb(base_io+7,0x19);
+ if(0x00 != (inb(base_io+7) & 0x01))
+ DSI_ERROR("program data not granted");
+ for(int_k = 0 ; int_k < size/3; int_k++) {
+ outb(base_io+1,*ptr++);
+ outb(base_io+2,0);
+ outb(base_io+1,*ptr++);
+ outb(base_io+2,*ptr++);
+ }
+ } else {
+ for(int_k = 0 ; int_k < size/3; int_k++) {
+ outb(base_io+0,*ptr++);
+ outb(base_io+1,*ptr++);
+ outb(base_io+2,*ptr++);
+ }
+ }
+ }
+ outb(base_io+7,0x11);
+ outb(base_io+7,3);
+
+ outb(base_io+4,data_0188 & 0xfb);
+
+ outb(base_io+3,data_0187);
+
+ return 0;
+error:
+ printf("sio%d: DSI SoftModem microcode load failed: <%s>\n",unit,ptr);
+ outb(base_io+7,0x00); \
+ outb(base_io+3,data_0187); \
+ outb(base_io+4,data_0188); \
+ return EIO;
+}
+#endif /* DSI_SOFT_MODEM */
/*
* support PnP cards if we are using 'em
@@ -4156,7 +3755,7 @@ siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
dev->id_iobase = d.port[0];
dev->id_irq = (1 << d.irq[0]);
- dev->id_ointr = siointr;
+ dev->id_intr = siointr;
dev->id_ri_flags = RI_FAST;
dev->id_drq = -1;
@@ -4173,7 +3772,6 @@ siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
printf("sio%d: probe failed\n", dev->id_unit);
}
#endif
-
#ifdef PC98
/*
* pc98 local function
@@ -4497,10 +4095,12 @@ com_cflag_and_speed_set( struct com_s *com, int cflag, int speed)
cfcr |= MOD8251_CLKX16;
if (epson_machine_id != 0x20) { /* XXX */
+ {
int tmp;
while (!((tmp = inb(com->sts_port)) & STS8251_TxEMP))
;
}
+ }
/* set baud rate from ospeed */
pc98_set_baud_rate( com, count );
@@ -4513,214 +4113,206 @@ com_cflag_and_speed_set( struct com_s *com, int cflag, int speed)
static int
pc98_ttspeedtab(struct com_s *com, int speed)
{
- int if_type, effect_sp, count = -1, mod;
+ int effect_sp, count=-1, mod;
- if_type = com->pc98_if_type & 0x0f;
-
- switch (com->pc98_if_type) {
- case COM_IF_INTERNAL:
- if (PC98SIO_baud_rate_port(if_type) != -1) {
- count = ttspeedtab(speed, if_8251_type[if_type].speedtab);
- if (count > 0) {
- count |= COM1_EXT_CLOCK;
- break;
- }
- }
-
- /* for *1CLK asynchronous! mode, TEFUTEFU */
- mod = (sysclock == 5) ? 2457600 : 1996800;
- effect_sp = ttspeedtab( speed, pc98speedtab );
- if ( effect_sp < 0 ) /* XXX */
- effect_sp = ttspeedtab( (speed - 1), pc98speedtab );
- if ( effect_sp <= 0 )
- return effect_sp;
- if ( effect_sp == speed )
- mod /= 16;
- if ( mod % effect_sp )
- return(-1);
- count = mod / effect_sp;
- if ( count > 65535 )
- return(-1);
- if ( effect_sp != speed )
- count |= 0x10000;
- break;
- case COM_IF_PC9861K_1:
- case COM_IF_PC9861K_2:
- count = 1;
- break;
- case COM_IF_IND_SS_1:
- case COM_IF_IND_SS_2:
- case COM_IF_PIO9032B_1:
- case COM_IF_PIO9032B_2:
- if ( speed == 0 ) return 0;
- count = ttspeedtab( speed, if_8251_type[if_type].speedtab );
- break;
- case COM_IF_B98_01_1:
- case COM_IF_B98_01_2:
- if ( speed == 0 ) return 0;
- count = ttspeedtab( speed, if_8251_type[if_type].speedtab );
-#ifdef B98_01_OLD
- if (count == 0 || count == 1) {
- count += 4;
- count |= 0x20000; /* x1 mode for 76800 and 153600 */
- }
+ switch ( com->pc98_if_type ) {
+ case COM_IF_INTERNAL:
+ /* for *1CLK asynchronous! mode , TEFUTEFU */
+ effect_sp = ttspeedtab( speed, pc98speedtab );
+ if ( effect_sp < 0 )
+ effect_sp = ttspeedtab( (speed-1), pc98speedtab );
+ if ( effect_sp <= 0 )
+ return effect_sp;
+ mod = (sysclock == 5 ? 2457600 : 1996800);
+ if ( effect_sp == speed )
+ mod /= 16;
+ count = mod / effect_sp;
+ if ( count > 65535 )
+ return(-1);
+ if ( effect_sp >= 2400 )
+ if ( !(sysclock != 5 &&
+ (effect_sp == 19200 || effect_sp == 38400)) )
+ if ( ( mod % effect_sp ) != 0 )
+ return(-1);
+ if ( effect_sp != speed )
+ count |= 0x10000;
+ break;
+#ifdef COM_IF_PC9861K
+ case COM_IF_PC9861K:
+ effect_sp = speed;
+ count = 1;
+ break;
+#endif
+#ifdef COM_IF_PIO9032B
+ case COM_IF_PIO9032B:
+ if ( speed == 0 ) return 0;
+ count = ttspeedtab( speed, comspeedtab_pio9032b );
+ if ( count < 0 ) return count;
+ effect_sp = speed;
+ break;
+#endif
+#ifdef COM_IF_B98_01
+ case COM_IF_B98_01:
+ effect_sp=speed;
+ count = ttspeedtab( speed, comspeedtab_b98_01 );
+ if ( count <= 3 )
+ return -1; /* invalid speed/count */
+ if ( count <= 5 )
+ count |= 0x10000; /* x1 mode for 76800 and 153600 */
+ else
+ count -= 4; /* x16 mode for slower */
+ break;
#endif
- break;
}
-
return count;
}
static void
-pc98_set_baud_rate( struct com_s *com, int count )
+pc98_set_baud_rate( struct com_s *com, int count)
{
- int if_type, io, s;
-
- if_type = com->pc98_if_type & 0x0f;
- io = com->iobase & 0xff00;
-
- switch (com->pc98_if_type) {
- case COM_IF_INTERNAL:
- if (PC98SIO_baud_rate_port(if_type) != -1) {
- if (count & COM1_EXT_CLOCK) {
- outb((Port_t)PC98SIO_baud_rate_port(if_type), count & 0xff);
- break;
- } else {
- outb((Port_t)PC98SIO_baud_rate_port(if_type), 0x09);
- }
- }
+ int s;
- if ( count < 0 ) {
- printf( "[ Illegal count : %d ]", count );
- return;
- } else if ( count == 0 )
- return;
- /* set i8253 */
- s = splclock();
- if (count != 3)
+ switch ( com->pc98_if_type ) {
+ case COM_IF_INTERNAL:
+ if ( count < 0 ) {
+ printf( "[ Illegal count : %d ]", count );
+ return;
+ } else if ( count == 0)
+ return;
+ /* set i8253 */
+ s = splclock();
outb( 0x77, 0xb6 );
- else
- outb( 0x77, 0xb4 );
- outb( 0x5f, 0);
- outb( 0x75, count & 0xff );
- outb( 0x5f, 0);
- outb( 0x75, (count >> 8) & 0xff );
- splx(s);
- break;
- case COM_IF_IND_SS_1:
- case COM_IF_IND_SS_2:
- outb(io | PC98SIO_intr_ctrl_port(if_type), 0);
- outb(io | PC98SIO_baud_rate_port(if_type), 0);
- outb(io | PC98SIO_baud_rate_port(if_type), 0xc0);
- outb(io | PC98SIO_baud_rate_port(if_type), (count >> 8) | 0x80);
- outb(io | PC98SIO_baud_rate_port(if_type), count & 0xff);
- break;
- case COM_IF_PIO9032B_1:
- case COM_IF_PIO9032B_2:
- outb(io | PC98SIO_baud_rate_port(if_type), count);
- break;
- case COM_IF_B98_01_1:
- case COM_IF_B98_01_2:
- outb(io | PC98SIO_baud_rate_port(if_type), count & 0x0f);
+ outb( 0x5f, 0);
+ outb( 0x75, count & 0xff );
+ outb( 0x5f, 0);
+ outb( 0x75, (count >> 8) & 0xff );
+ splx(s);
+ break;
+#if 0
+#ifdef COM_IF_PC9861K
+ case COM_IF_PC9861K:
+ break;
+ /* ext. RS232C board: speed is determined by DIP switch */
+#endif
+#endif /* 0 */
+#ifdef COM_IF_PIO9032B
+ case COM_IF_PIO9032B:
+ outb( com_addr[unit], count & 0x07 );
+ break;
+#endif
+#ifdef COM_IF_B98_01
+ case COM_IF_B98_01:
+ outb( com->iobase, count & 0x0f );
#ifdef B98_01_OLD
- /*
- * Some old B98_01 board should be controlled
- * in different way, but this hasn't been tested yet.
- */
- outb(io | PC98SIO_func_port(if_type),
- (count & 0x20000) ? 0xf0 : 0xf2);
+ /* some old board should be controlled in different way,
+ but this hasn't been tested yet.*/
+ outb( com->iobase+2, ( count & 0x10000 ) ? 0xf0 : 0xf2 );
+#endif
+ break;
#endif
- break;
}
}
static int
-pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
+pc98_check_if_type( int iobase, struct siodev *iod)
{
- int irr, io, if_type, tmp;
+ int irr = 0, tmp = 0;
+ int ret = 0;
static short irq_tab[2][8] = {
{ 3, 5, 6, 9, 10, 12, 13, -1},
{ 3, 10, 12, 13, 5, 6, 9, -1}
};
-
- iod->if_type = if_type = (dev->id_flags >> 24) & 0xff;
- if ((if_type < 0 || if_type > COM_IF_END1) &&
- (if_type < 0x10 || if_type > COM_IF_END2))
- return(-1);
- if_type &= 0x0f;
iod->irq = 0;
- io = dev->id_iobase & 0xff00;
-
- if (IS_8251(iod->if_type)) {
- if (PC98SIO_func_port(if_type) != -1) {
- outb(io | PC98SIO_func_port(if_type), 0xf2);
- tmp = ttspeedtab(9600, if_8251_type[if_type].speedtab);
- if (tmp != -1 && PC98SIO_baud_rate_port(if_type) != -1)
- outb(io | PC98SIO_baud_rate_port(if_type), tmp);
- }
-
- iod->cmd = io | PC98SIO_cmd_port(if_type);
- iod->sts = io | PC98SIO_sts_port(if_type);
- iod->mod = io | PC98SIO_in_modem_port(if_type);
- iod->ctrl = io | PC98SIO_intr_ctrl_port(if_type);
-
- if (iod->if_type == COM_IF_INTERNAL) {
- iod->irq = 4;
-
- /* XXX check new internal port. */
- outb(0x138, 0);
- DELAY(10);
- for (tmp = 0; tmp < 100; tmp++) {
- if ((inb(0x138) & 1) == 0) {
- PC98SIO_baud_rate_port(if_type) = 0x13a;
- if_8251_type[if_type].name = " (internal fast)";
- if_8251_type[if_type].speedtab = pc98fast_speedtab;
+ switch ( iobase & 0xff ) {
+ case IO_COM1:
+ iod->if_type = COM_IF_INTERNAL;
+ ret = 0; iod->irq = 4; break;
+#ifdef COM_IF_PC9861K
+ case IO_COM2:
+ iod->if_type = COM_IF_PC9861K;
+ ret = 1; irr = 0; tmp = 3; break;
+ case IO_COM3:
+ iod->if_type = COM_IF_PC9861K;
+ ret = 2; irr = 1; tmp = 3; break;
+#endif
+#ifdef COM_IF_PIO9032B
+ case IO_COM_PIO9032B_2:
+ iod->if_type = COM_IF_PIO9032B;
+ ret = 1; irr = 0; tmp = 7; break;
+ case IO_COM_PIO9032B_3:
+ iod->if_type = COM_IF_PIO9032B;
+ ret = 2; irr = 1; tmp = 7; break;
+#endif
+#ifdef COM_IF_B98_01
+ case IO_COM_B98_01_2:
+ iod->if_type = COM_IF_B98_01;
+ ret = 1; irr = 0; tmp = 7;
+ outb(iobase + 2, 0xf2);
+ outb(iobase, 4);
+ break;
+ case IO_COM_B98_01_3:
+ iod->if_type = COM_IF_B98_01;
+ ret = 2; irr = 1; tmp = 7;
+ outb(iobase + 2, 0xf2);
+ outb(iobase , 4);
break;
- }
- DELAY(1);
- }
- } else {
- tmp = inb( iod->mod ) & if_8251_type[if_type].irr_mask;
- if ((dev->id_iobase & 0xff) == IO_COM2)
- iod->irq = irq_tab[0][tmp];
- else
- iod->irq = irq_tab[1][tmp];
- }
- } else {
- irr = if_16550a_type[if_type].irr_read;
-#ifdef COM_MULTIPORT
- if (!COM_ISMULTIPORT(dev) || dev->id_unit == COM_MPMASTER(dev))
#endif
- if (irr != -1) {
- tmp = inb(io | irr);
- if (dev->id_iobase & 0x01) /* XXX depend on RSB-384 */
- iod->irq = irq_tab[1][tmp >> 3];
- else
- iod->irq = irq_tab[0][tmp & 0x07];
- }
+ default:
+ if((iobase & 0x0f0) == 0xd0){
+ iod->if_type = MC16550;
+ return 0;
+ }
+ return -1;
}
- if ( iod->irq == -1 ) return -1;
+ iod->cmd = ( iobase & 0xff00 )|PC98SIO_cmd_port(ret);
+ iod->sts = ( iobase & 0xff00 )|PC98SIO_sts_port(ret);
+ iod->mod = ( iobase & 0xff00 )|PC98SIO_in_modem_port(ret);
+ iod->ctrl = ( iobase & 0xff00 )|PC98SIO_intr_ctrl_port(ret);
+
+ if ( iod->irq == 0 ) {
+ tmp &= inb( iod->mod );
+ iod->irq = irq_tab[irr][tmp];
+ if ( iod->irq == -1 ) return -1;
+ }
return 0;
}
static int
-pc98_set_ioport( struct com_s *com, int id_flags )
+pc98_set_ioport( struct com_s *com, int io_base )
{
- int io, if_type;
+ int a, io, type;
- if_type = (id_flags >> 24) & 0xff;
- if (IS_8251(if_type)) {
- pc98_check_sysclock();
- io = com->iobase & 0xff00;
- com->pc98_if_type = if_type;
- if_type &= 0x0f;
- com->data_port = io | PC98SIO_data_port(if_type);
- com->cmd_port = io | PC98SIO_cmd_port(if_type);
- com->sts_port = io | PC98SIO_sts_port(if_type);
- com->in_modem_port = io | PC98SIO_in_modem_port(if_type);
- com->intr_ctrl_port = io | PC98SIO_intr_ctrl_port(if_type);
- return 0;
+ switch ( io_base & 0xff ) {
+ case IO_COM1: a = 0; io = 0; type = COM_IF_INTERNAL;
+ pc98_check_sysclock(); break;
+#ifdef COM_IF_PC9861K
+ case IO_COM2: a = 1; io = 0; type = COM_IF_PC9861K; break;
+ case IO_COM3: a = 2; io = 0; type = COM_IF_PC9861K; break;
+#endif /* COM_IF_PC9861K */
+#ifdef COM_IF_PIO9032B
+ /* PIO9032B : I/O address is changeable */
+ case IO_COM_PIO9032B_2:
+ a = 1; io = io_base & 0xff00;
+ type = COM_IF_PIO9032B; break;
+ case IO_COM_PIO9032B_3:
+ a = 2; io = io_base & 0xff00;
+ type = COM_IF_PIO9032B; break;
+#endif /* COM_IF_PIO9032B */
+#ifdef COM_IF_B98_01
+ case IO_COM_B98_01_2:
+ a = 1; io = 0; type = COM_IF_B98_01; break;
+ case IO_COM_B98_01_3:
+ a = 2; io = 0; type = COM_IF_B98_01; break;
+#endif /* COM_IF_B98_01*/
+ default: /* i/o address not match */
+ return -1;
}
- return -1;
+ com->pc98_if_type = type;
+ com->data_port = io | PC98SIO_data_port(a);
+ com->cmd_port = io | PC98SIO_cmd_port(a);
+ com->sts_port = io | PC98SIO_sts_port(a);
+ com->in_modem_port = io | PC98SIO_in_modem_port(a);
+ com->intr_ctrl_port = io | PC98SIO_intr_ctrl_port(a);
+ return 0;
}
#endif /* PC98 defined */
diff --git a/sys/pc98/pc98/sioreg.h b/sys/pc98/pc98/sioreg.h
new file mode 100644
index 000000000000..840df10841be
--- /dev/null
+++ b/sys/pc98/pc98/sioreg.h
@@ -0,0 +1,119 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * 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 University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)comreg.h 7.2 (Berkeley) 5/9/91
+ * $Id: sioreg.h,v 1.6 1997/06/04 10:27:53 kato Exp $
+ */
+
+
+/* 16 bit baud rate divisor (lower byte in dca_data, upper in dca_ier) */
+#if defined(PC98)
+#define COMBRD(x) (7372800 / (16*(x)))
+#else
+#define COMBRD(x) (1843200 / (16*(x)))
+#endif
+
+/* interrupt enable register */
+#define IER_ERXRDY 0x1
+#define IER_ETXRDY 0x2
+#define IER_ERLS 0x4
+#define IER_EMSC 0x8
+
+/* interrupt identification register */
+#define IIR_IMASK 0xf
+#define IIR_RXTOUT 0xc
+#define IIR_RLS 0x6
+#define IIR_RXRDY 0x4
+#define IIR_TXRDY 0x2
+#define IIR_NOPEND 0x1
+#define IIR_MLSC 0x0
+#define IIR_FIFO_MASK 0xc0 /* set if FIFOs are enabled */
+
+/* fifo control register */
+#define FIFO_ENABLE 0x01
+#define FIFO_RCV_RST 0x02
+#define FIFO_XMT_RST 0x04
+#define FIFO_DMA_MODE 0x08
+#define FIFO_RX_LOW 0x00
+#define FIFO_RX_MEDL 0x40
+#define FIFO_RX_MEDH 0x80
+#define FIFO_RX_HIGH 0xc0
+
+/* character format control register */
+#define CFCR_DLAB 0x80
+#define CFCR_SBREAK 0x40
+#define CFCR_PZERO 0x30
+#define CFCR_PONE 0x20
+#define CFCR_PEVEN 0x10
+#define CFCR_PODD 0x00
+#define CFCR_PENAB 0x08
+#define CFCR_STOPB 0x04
+#define CFCR_8BITS 0x03
+#define CFCR_7BITS 0x02
+#define CFCR_6BITS 0x01
+#define CFCR_5BITS 0x00
+
+/* modem control register */
+#define MCR_LOOPBACK 0x10
+#define MCR_IENABLE 0x08
+#define MCR_DRS 0x04
+#define MCR_RTS 0x02
+#define MCR_DTR 0x01
+
+/* line status register */
+#define LSR_RCV_FIFO 0x80
+#define LSR_TSRE 0x40
+#define LSR_TXRDY 0x20
+#define LSR_BI 0x10
+#define LSR_FE 0x08
+#define LSR_PE 0x04
+#define LSR_OE 0x02
+#define LSR_RXRDY 0x01
+#define LSR_RCV_MASK 0x1f
+
+/* modem status register */
+#define MSR_DCD 0x80
+#define MSR_RI 0x40
+#define MSR_DSR 0x20
+#define MSR_CTS 0x10
+#define MSR_DDCD 0x08
+#define MSR_TERI 0x04
+#define MSR_DDSR 0x02
+#define MSR_DCTS 0x01
+
+/* speed to initialize to during chip tests */
+#define SIO_TEST_SPEED 9600
+
+/* default serial console speed if not set with sysctl or probed from boot */
+#ifndef CONSPEED
+#define CONSPEED 9600
+#endif
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c
index bfce06877b62..e85a1b317454 100644
--- a/sys/pc98/pc98/syscons.c
+++ b/sys/pc98/pc98/syscons.c
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1992-1998 Sen Schmidt
+ * Copyright (c) 1992-1995 Sen Schmidt
* 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,
- * without modification, immediately at the beginning of the file.
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,16 +25,13 @@
* (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: syscons.c,v 1.108 1999/01/18 14:48:34 kato Exp $
+ * $Id: syscons.c,v 1.100 1998/08/28 12:45:43 kato Exp $
*/
#include "sc.h"
-#include "splash.h"
#include "apm.h"
#include "opt_ddb.h"
#include "opt_devfs.h"
-#include "opt_vesa.h"
-#include "opt_vm86.h"
#include "opt_syscons.h"
#if NSC > 0
@@ -60,33 +57,36 @@
#include <machine/psl.h>
#include <machine/frame.h>
#include <machine/pc/display.h>
-#include <machine/pc/vesa.h>
#include <machine/apm_bios.h>
#include <machine/random.h>
+#include <machine/bootinfo.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
-#include <dev/kbd/kbdreg.h>
-#include <dev/fb/fbreg.h>
-#include <dev/fb/splashreg.h>
-
#ifdef PC98
#define KANJI
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/timerreg.h>
+#include <i386/isa/kbdtables.h>
+#include <i386/isa/kbdio.h>
#include <pc98/pc98/syscons.h>
#else
-#include <dev/fb/vgareg.h>
-#include <dev/syscons/syscons.h>
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/timerreg.h>
+#include <i386/isa/kbdtables.h>
+#include <i386/isa/kbdio.h>
+#include <i386/isa/syscons.h>
#endif /* PC98 */
+#if defined(PC98) && defined(LINE30)
+#include <pc98/pc98/30line.h>
+#endif
+
#if !defined(MAXCONS)
#define MAXCONS 16
#endif
@@ -111,6 +111,11 @@
#define COLD 0
#define WARM 1
+#define VESA_MODE(x) ((x) >= M_VESA_BASE)
+
+#define MODE_MAP_SIZE (M_VGA_CG320 + 1)
+#define MODE_PARAM_SIZE 64
+
#define DEFAULT_BLANKTIME (5*60) /* 5 minutes */
#define MAX_BLANKTIME (7*24*60*60) /* 7 days!? */
@@ -131,6 +136,9 @@ typedef struct old_mouse_info {
} u;
} old_mouse_info_t;
+/* XXX use sc_bcopy where video memory is concerned */
+extern void generic_bcopy(const void *, void *, size_t);
+
static default_attr user_default = {
(FG_LIGHTGREY | BG_BLACK) << 8,
(FG_BLACK | BG_LIGHTGREY) << 8
@@ -159,7 +167,9 @@ static void *sc_console_devfs_token;
static scr_stat *new_scp, *old_scp;
static term_stat kernel_console;
static default_attr *current_default;
-static int sc_flags;
+static int flags = 0;
+static int sc_port = IO_KBD;
+static KBDC sc_kbdc = NULL;
static char init_done = COLD;
static u_short sc_buffer[ROW*COL];
static char shutdown_in_progress = FALSE;
@@ -168,38 +178,51 @@ static char switch_in_progress = FALSE;
static char write_in_progress = FALSE;
static char blink_in_progress = FALSE;
static int blinkrate = 0;
-static int adapter = -1;
-static int keyboard = -1;
-static keyboard_t *kbd;
+#ifndef PC98
+ u_int crtc_addr = MONO_BASE;
+#endif
+ char crtc_type = KD_MONO;
+ char crtc_vga = FALSE;
+static u_char shfts = 0, ctls = 0, alts = 0, agrs = 0, metas = 0;
+static u_char accents = 0;
+#ifdef PC98
+static u_char nlkcnt = 0, slkcnt = 0, alkcnt = 0;
+#else
+static u_char nlkcnt = 0, clkcnt = 0, slkcnt = 0, alkcnt = 0;
+#endif
+static const u_int n_fkey_tab = sizeof(fkey_tab) / sizeof(*fkey_tab);
static int delayed_next_scr = FALSE;
static long scrn_blank_time = 0; /* screen saver timeout value */
-static int scrn_blanked = FALSE; /* screen saver active flag */
+ int scrn_blanked = 0; /* screen saver active flag */
static long scrn_time_stamp;
static int saver_mode = CONS_LKM_SAVER; /* LKM/user saver */
static int run_scrn_saver = FALSE; /* should run the saver? */
static int scrn_idle = FALSE; /* about to run the saver */
-static int scrn_saver_failed;
u_char scr_map[256];
u_char scr_rmap[256];
-static int initial_video_mode; /* initial video mode # */
+ char *video_mode_ptr = NULL;
+static int bios_video_mode; /* video mode # set by BIOS */
int fonts_loaded = 0
#ifdef STD8X16FONT
| FONT_16
#endif
;
- u_char font_8[256*8];
- u_char font_14[256*14];
+ char font_8[256*8];
+ char font_14[256*14];
#ifdef STD8X16FONT
extern
#endif
- u_char font_16[256*16];
- u_char palette[256*3];
-static u_char *cut_buffer;
+ unsigned char font_16[256*16];
+ char palette[256*3];
+static char *mode_map[MODE_MAP_SIZE];
+static char vgaregs[MODE_PARAM_SIZE];
+static char vgaregs2[MODE_PARAM_SIZE];
+static int rows_offset = 1;
+static char *cut_buffer;
static int cut_buffer_size;
-static int mouse_level; /* sysmouse protocol level */
+static int mouse_level = 0; /* sysmouse protocol level */
static mousestatus_t mouse_status = { 0, 0, 0, 0, 0, 0 };
-#ifndef PC98
static u_short mouse_and_mask[16] = {
0xc000, 0xe000, 0xf000, 0xf800,
0xfc00, 0xfe00, 0xff00, 0xff80,
@@ -212,22 +235,17 @@ static u_short mouse_or_mask[16] = {
0x0c00, 0x0c00, 0x0600, 0x0600,
0x0000, 0x0000, 0x0000, 0x0000
};
-#endif
- int sc_history_size = SC_HISTORY_SIZE;
-static int extra_history_size =
+static int extra_history_size =
SC_MAX_HISTORY_SIZE - SC_HISTORY_SIZE * MAXCONS;
static void none_saver(int blank) { }
static void (*current_saver)(int blank) = none_saver;
- d_ioctl_t *sc_user_ioctl;
+static void (*default_saver)(int blank) = none_saver;
+int (*sc_user_ioctl)(dev_t dev, int cmd, caddr_t data,
+ int flag, struct proc *p) = NULL;
static int sticky_splash = FALSE;
-static struct {
- u_int8_t cursor_start;
- u_int8_t cursor_end;
- u_int8_t shift_state;
- } bios_value;
/* OS specific stuff */
#ifdef not_yet_done
@@ -243,92 +261,81 @@ static struct tty sccons[MAXCONS+2];
#endif
#define SC_MOUSE 128
#define SC_CONSOLE 255
-u_short *Crtat;
#ifdef PC98
-u_short *Atrat;
static u_char default_kanji = UJIS;
+u_short *Crtat;
+u_short *Atrat;
+#else
+#define MONO_BUF pa_to_va(0xB0000)
+#define CGA_BUF pa_to_va(0xB8000)
+u_short *Crtat;
#endif
static const int nsccons = MAXCONS+2;
#define WRAPHIST(scp, pointer, offset)\
- ((scp)->history + ((((pointer) - (scp)->history) + (scp)->history_size \
- + (offset)) % (scp)->history_size))
+ ((scp->history) + ((((pointer) - (scp->history)) + (scp->history_size)\
+ + (offset)) % (scp->history_size)))
#ifdef PC98
#define WRAPHIST_A(scp, pointer, offset)\
- ((scp->his_atr) + ((((pointer) - (scp->his_atr)) + (scp)->history_size \
- + (offset)) % (scp)->history_size))
+ ((scp->his_atr) + ((((pointer) - (scp->his_atr)) + (scp->history_size)\
+ + (offset)) % (scp->history_size)))
#endif
#define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG)
-/* some useful macros */
-#define kbd_read_char(kbd, wait) \
- (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait))
-#define kbd_check_char(kbd) \
- (*kbdsw[(kbd)->kb_index]->check_char)((kbd))
-#define kbd_enable(kbd) \
- (*kbdsw[(kbd)->kb_index]->enable)((kbd))
-#define kbd_disable(kbd) \
- (*kbdsw[(kbd)->kb_index]->disable)((kbd))
-#define kbd_lock(kbd, lockf) \
- (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf))
-#define kbd_ioctl(kbd, cmd, arg) \
- (((kbd) == NULL) ? \
- ENODEV : (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg)))
-#define kbd_clear_state(kbd) \
- (*kbdsw[(kbd)->kb_index]->clear_state)((kbd))
-#define kbd_get_fkeystr(kbd, fkey, len) \
- (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len))
+/* this should really be in `rtc.h' */
+#define RTC_EQUIPMENT 0x14
/* prototypes */
static int scattach(struct isa_device *dev);
-static kbd_callback_func_t sckbdevent;
static int scparam(struct tty *tp, struct termios *t);
static int scprobe(struct isa_device *dev);
-static int scvidprobe(int unit, int flags, int cons);
-static int sckbdprobe(int unit, int flags, int cons);
+static int scvidprobe(int unit, int flags);
+static int sckbdprobe(int unit, int flags);
static void scstart(struct tty *tp);
static void scmousestart(struct tty *tp);
static void scinit(void);
static void scshutdown(int howto, void *arg);
-static u_int scgetc(keyboard_t *kbd, u_int flags);
+static void map_mode_table(char *map[], char *table, int max);
+static int map_mode_num(int mode);
+static char *get_mode_param(scr_stat *scp, int mode);
+static u_int scgetc(u_int flags);
#define SCGETC_CN 1
#define SCGETC_NONBLOCK 2
-static int sccngetch(int flags);
static void sccnupdate(scr_stat *scp);
+static scr_stat *get_scr_stat(dev_t dev);
static scr_stat *alloc_scp(void);
static void init_scp(scr_stat *scp);
-static void get_bios_values(void);
static void sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark);
static int get_scr_num(void);
static timeout_t scrn_timer;
static void scrn_update(scr_stat *scp, int show_cursor);
-#if NSPLASH > 0
-static int scsplash_callback(int);
-static void scsplash_saver(int show);
-static int add_scrn_saver(void (*this_saver)(int));
-static int remove_scrn_saver(void (*this_saver)(int));
-static int set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border);
-static int restore_scrn_saver_mode(scr_stat *scp, int changemode);
static void stop_scrn_saver(void (*saver)(int));
static int wait_scrn_saver_stop(void);
-#define scsplash_stick(stick) (sticky_splash = (stick))
-#else
-#define scsplash_stick(stick)
-#endif /* NSPLASH */
+static void clear_screen(scr_stat *scp);
static int switch_scr(scr_stat *scp, u_int next_scr);
static void exchange_scr(void);
+static void move_crsr(scr_stat *scp, int x, int y);
static void scan_esc(scr_stat *scp, u_char c);
-static void ansi_put(scr_stat *scp, u_char *buf, int len);
static void draw_cursor_image(scr_stat *scp);
static void remove_cursor_image(scr_stat *scp);
-static void move_crsr(scr_stat *scp, int x, int y);
+static void ansi_put(scr_stat *scp, u_char *buf, int len);
+static u_char *get_fstr(u_int c, u_int *len);
static void history_to_screen(scr_stat *scp);
static int history_up_line(scr_stat *scp);
static int history_down_line(scr_stat *scp);
static int mask2attr(struct term_stat *term);
-static int save_kbd_state(scr_stat *scp);
-static int update_kbd_state(int state, int mask);
-static int update_kbd_leds(int which);
+static void set_keyboard(int command, int data);
+static void update_leds(int which);
+static void set_vgaregs(char *modetable);
+static void read_vgaregs(char *buf);
+#define COMP_IDENTICAL 0
+#define COMP_SIMILAR 1
+#define COMP_DIFFERENT 2
+static int comp_vgaregs(u_char *buf1, u_char *buf2);
+static void dump_vgaregs(u_char *buf);
+#define PARAM_BUFSIZE 6
+static void set_font_mode(u_char *buf);
+static void set_normal_mode(u_char *buf);
static void set_destructive_cursor(scr_stat *scp);
static void set_mouse_pos(scr_stat *scp);
static int skip_spc_right(scr_stat *scp, u_short *p);
@@ -344,16 +351,16 @@ static void draw_mouse_image(scr_stat *scp);
static void remove_mouse_image(scr_stat *scp);
static void draw_cutmarking(scr_stat *scp);
static void remove_cutmarking(scr_stat *scp);
+static void save_palette(void);
static void do_bell(scr_stat *scp, int pitch, int duration);
static timeout_t blink_screen;
-
-static cn_probe_t sccnprobe;
-static cn_init_t sccninit;
-static cn_getc_t sccngetc;
-static cn_checkc_t sccncheckc;
-static cn_putc_t sccnputc;
-
-CONS_DRIVER(sc, sccnprobe, sccninit, sccngetc, sccncheckc, sccnputc);
+#ifdef SC_SPLASH_SCREEN
+static void scsplash_init(void);
+static void scsplash(int show);
+#define scsplash_stick(stick) (sticky_splash = (stick))
+#else
+#define scsplash_stick(stick)
+#endif
struct isa_driver scdriver = {
scprobe, scattach, "sc", 1
@@ -364,6 +371,7 @@ static d_close_t scclose;
static d_read_t scread;
static d_write_t scwrite;
static d_ioctl_t scioctl;
+static d_devtotty_t scdevtotty;
static d_mmap_t scmmap;
#define CDEV_MAJOR 12
@@ -412,27 +420,31 @@ at2pc98(unsigned int attr)
}
#endif
+/*
+ * These functions need to be before calls to them so they can be inlined.
+ */
static void
draw_cursor_image(scr_stat *scp)
{
+ u_short cursor_image, *ptr;
+ u_short prev_image;
#ifdef PC98
- (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, scp->xpos, scp->ypos);
+ int pos = scp->cursor_pos - scp->scr_buf;
+ while((inb(TEXT_GDC + 0) & 0x04) == 0) {}
+ outb(TEXT_GDC + 2, 0x49); /* CSRW */
+ outb(TEXT_GDC + 0, pos & 0xff); /* EADl */
+ outb(TEXT_GDC + 0, pos >> 8); /* EADh */
#else
- u_short cursor_image;
- u_short *ptr;
- u_short prev_image;
+ ptr = Crtat + (scp->cursor_pos - scp->scr_buf);
- if (ISPIXELSC(scp)) {
+ if (VESA_MODE(scp->mode)) {
sc_bcopy(scp, scp->scr_buf, scp->cursor_pos - scp->scr_buf,
scp->cursor_pos - scp->scr_buf, 1);
return;
}
- ptr = (u_short *)(scp->adp->va_window)
- + (scp->cursor_pos - scp->scr_buf);
-
/* do we have a destructive cursor ? */
- if (sc_flags & CHAR_CURSOR) {
+ if (flags & CHAR_CURSOR) {
prev_image = scp->cursor_saveunder;
cursor_image = *ptr & 0x00ff;
if (cursor_image == DEAD_CHAR)
@@ -443,7 +455,7 @@ draw_cursor_image(scr_stat *scp)
if (prev_image != cursor_image)
set_destructive_cursor(scp);
/* modify cursor_image */
- if (!(sc_flags & BLINK_CURSOR)||((sc_flags & BLINK_CURSOR)&&(blinkrate & 4))){
+ if (!(flags & BLINK_CURSOR)||((flags & BLINK_CURSOR)&&(blinkrate & 4))){
/*
* When the mouse pointer is at the same position as the cursor,
* the cursor bitmap needs to be updated even if the char under
@@ -459,7 +471,7 @@ draw_cursor_image(scr_stat *scp)
} else {
cursor_image = (*(ptr) & 0x00ff) | *(scp->cursor_pos) & 0xff00;
scp->cursor_saveunder = cursor_image;
- if (!(sc_flags & BLINK_CURSOR)||((sc_flags & BLINK_CURSOR)&&(blinkrate & 4))){
+ if (!(flags & BLINK_CURSOR)||((flags & BLINK_CURSOR)&&(blinkrate & 4))){
if ((cursor_image & 0x7000) == 0x7000) {
cursor_image &= 0x8fff;
if(!(cursor_image & 0x0700))
@@ -479,13 +491,11 @@ static void
remove_cursor_image(scr_stat *scp)
{
#ifndef PC98
- if (ISPIXELSC(scp))
+ if (VESA_MODE(scp->mode))
sc_bcopy(scp, scp->scr_buf, scp->cursor_oldpos - scp->scr_buf,
- scp->cursor_oldpos - scp->scr_buf, 0);
+ scp->cursor_oldpos - scp->scr_buf, 0);
else
- *((u_short *)(scp->adp->va_window)
- + (scp->cursor_oldpos - scp->scr_buf))
- = scp->cursor_saveunder;
+ *(Crtat + (scp->cursor_oldpos - scp->scr_buf)) = scp->cursor_saveunder;
#endif
}
@@ -511,72 +521,303 @@ move_crsr(scr_stat *scp, int x, int y)
static int
scprobe(struct isa_device *dev)
{
- if (!scvidprobe(dev->id_unit, dev->id_flags, FALSE)) {
+ if (!scvidprobe(dev->id_unit, dev->id_flags)) {
if (bootverbose)
printf("sc%d: no video adapter is found.\n", dev->id_unit);
return (0);
}
- return ((sckbdprobe(dev->id_unit, dev->id_flags, FALSE)) ? -1 : 0);
+ sc_port = dev->id_iobase;
+ if (sckbdprobe(dev->id_unit, dev->id_flags))
+ return (IO_KBDSIZE);
+ else
+ return ((dev->id_flags & DETECT_KBD) ? 0 : IO_KBDSIZE);
}
/* probe video adapters, return TRUE if found */
static int
-scvidprobe(int unit, int flags, int cons)
+scvidprobe(int unit, int flags)
{
- video_adapter_t *adp;
+ /*
+ * XXX don't try to `printf' anything here, the console may not have
+ * been configured yet.
+ */
+ u_short volatile *cp;
+ u_short was;
+ u_int pa;
+ u_int segoff;
+
+ /* do this test only once */
+ if (init_done != COLD)
+ return (Crtat != 0);
/*
- * Access the video adapter driver through the back door!
- * Video adapter drivers need to be configured before syscons.
- * However, when syscons is being probed as the low-level console,
- * they have not been initialized yet. We force them to initialize
- * themselves here. XXX
+ * Finish defaulting crtc variables for a mono screen. Crtat is a
+ * bogus common variable so that it can be shared with pcvt, so it
+ * can't be statically initialized. XXX.
*/
- vid_configure(cons ? VIO_PROBE_ONLY : 0);
-
- /* allocate a frame buffer */
- if (adapter < 0) {
- adapter = vid_allocate("*", -1, (void *)&adapter);
- if (adapter < 0)
+#ifdef PC98
+ Crtat = (u_short *)TEXT_VRAM;
+ Atrat = (u_short *)TEXT_VRAM + ATTR_OFFSET;
+ crtc_type = KD_PC98;
+#else
+ Crtat = (u_short *)MONO_BUF;
+ crtc_type = KD_MONO;
+ /* If CGA memory seems to work, switch to color. */
+ cp = (u_short *)CGA_BUF;
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ bios_video_mode = *(u_char *)pa_to_va(0x449);
+ if (bootinfo.bi_vesa == 0x102) {
+ bios_video_mode = bootinfo.bi_vesa;
+ Crtat = (u_short *)pa_to_va(0xA0000);
+ crtc_addr = COLOR_BASE;
+ crtc_type = KD_VGA;
+ bzero(Crtat, 800*600/8);
+ } else if (*cp == 0xA55A) {
+ Crtat = (u_short *)CGA_BUF;
+ crtc_addr = COLOR_BASE;
+ crtc_type = KD_CGA;
+ } else {
+ cp = Crtat;
+ was = *cp;
+ *cp = (u_short) 0xA55A;
+ if (*cp != 0xA55A) {
+ /* no screen at all, bail out */
+ Crtat = 0;
return FALSE;
+ }
}
- adp = vid_get_adapter(adapter); /* shouldn't fail */
+ *cp = was;
- Crtat = (u_short *)adp->va_window;
-#ifdef PC98
- Atrat = Crtat + ATTR_OFFSET;
-#endif
- initial_video_mode = adp->va_initial_mode;
+ if (!VESA_MODE(bios_video_mode)) {
+ /*
+ * Check rtc and BIOS date area.
+ * XXX: don't use BIOSDATA_EQUIPMENT, it is not a dead copy
+ * of RTC_EQUIPMENT. The bit 4 and 5 of the ETC_EQUIPMENT are
+ * zeros for EGA and VGA. However, the EGA/VGA BIOS will set
+ * these bits in BIOSDATA_EQUIPMENT according to the monitor
+ * type detected.
+ */
+ switch ((rtcin(RTC_EQUIPMENT) >> 4) & 3) { /* bit 4 and 5 */
+ case 0: /* EGA/VGA, or nothing */
+ crtc_type = KD_EGA;
+ /* the color adapter may be in the 40x25 mode... XXX */
+ break;
+ case 1: /* CGA 40x25 */
+ /* switch to the 80x25 mode? XXX */
+ /* FALL THROUGH */
+ case 2: /* CGA 80x25 */
+ /* `crtc_type' has already been set... */
+ /* crtc_type = KD_CGA; */
+ break;
+ case 3: /* MDA */
+ /* `crtc_type' has already been set... */
+ /* crtc_type = KD_MONO; */
+ break;
+ }
+
+ /* is this a VGA or higher ? */
+ outb(crtc_addr, 7);
+ if (inb(crtc_addr) == 7) {
+ crtc_type = KD_VGA;
+ crtc_vga = TRUE;
+ read_vgaregs(vgaregs);
+
+ /* Get the BIOS video mode pointer */
+ segoff = *(u_int *)pa_to_va(0x4a8);
+ pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff);
+ if (ISMAPPED(pa, sizeof(u_int))) {
+ segoff = *(u_int *)pa_to_va(pa);
+ pa = ((segoff & 0xffff0000) >> 12) + (segoff & 0xffff);
+ if (ISMAPPED(pa, MODE_PARAM_SIZE))
+ video_mode_ptr = (char *)pa_to_va(pa);
+ }
+ }
+ }
+#endif /* PC98 */
return TRUE;
}
/* probe the keyboard, return TRUE if found */
static int
-sckbdprobe(int unit, int flags, int cons)
+sckbdprobe(int unit, int flags)
{
- /* access the keyboard driver through the backdoor! */
- kbd_configure(cons ? KB_CONF_PROBE_ONLY : 0);
+ int codeset;
+ int c = -1;
+ int m;
+ int res, id;
- /* allocate a keyboard and register the keyboard event handler */
- if (keyboard < 0) {
- keyboard = kbd_allocate("*", -1, (void *)&keyboard, sckbdevent, NULL);
- if (keyboard < 0)
- return FALSE;
+ sc_kbdc = kbdc_open(sc_port);
+#ifndef PC98
+ if (!kbdc_lock(sc_kbdc, TRUE)) {
+ /* driver error? */
+ printf("sc%d: unable to lock the controller.\n", unit);
+ return ((flags & DETECT_KBD) ? FALSE : TRUE);
+ }
+
+ /* discard anything left after UserConfig */
+ empty_both_buffers(sc_kbdc, 10);
+
+ /* save the current keyboard controller command byte */
+ m = kbdc_get_device_mask(sc_kbdc) & ~KBD_KBD_CONTROL_BITS;
+ c = get_controller_command_byte(sc_kbdc);
+ if (c == -1) {
+ /* CONTROLLER ERROR */
+ printf("sc%d: unable to get the current command byte value.\n", unit);
+ goto fail;
+ }
+ if (bootverbose)
+ printf("sc%d: the current keyboard controller command byte %04x\n",
+ unit, c);
+#if 0
+ /* override the keyboard lock switch */
+ c |= KBD_OVERRIDE_KBD_LOCK;
+#endif
+
+ /*
+ * The keyboard may have been screwed up by the boot block.
+ * We may just be able to recover from error by testing the controller
+ * and the keyboard port. The controller command byte needs to be saved
+ * before this recovery operation, as some controllers seem to set
+ * the command byte to particular values.
+ */
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+
+ /* enable the keyboard port, but disable the keyboard intr. */
+ if (!set_controller_command_byte(sc_kbdc,
+ KBD_KBD_CONTROL_BITS,
+ KBD_ENABLE_KBD_PORT | KBD_DISABLE_KBD_INT)) {
+ /* CONTROLLER ERROR
+ * there is very little we can do...
+ */
+ printf("sc%d: unable to set the command byte.\n", unit);
+ goto fail;
+ }
+
+ /*
+ * Check if we have an XT keyboard before we attempt to reset it.
+ * The procedure assumes that the keyboard and the controller have
+ * been set up properly by BIOS and have not been messed up
+ * during the boot process.
+ */
+ codeset = -1;
+ if (flags & XT_KEYBD)
+ /* the user says there is a XT keyboard */
+ codeset = 1;
+#ifdef DETECT_XT_KEYBOARD
+ else if ((c & KBD_TRANSLATION) == 0) {
+ /* SET_SCANCODE_SET is not always supported; ignore error */
+ if (send_kbd_command_and_data(sc_kbdc, KBDC_SET_SCANCODE_SET, 0)
+ == KBD_ACK)
+ codeset = read_kbd_data(sc_kbdc);
+ }
+ if (bootverbose)
+ printf("sc%d: keyboard scancode set %d\n", unit, codeset);
+#endif /* DETECT_XT_KEYBOARD */
+
+ if (flags & KBD_NORESET) {
+ write_kbd_command(sc_kbdc, KBDC_ECHO);
+ if (read_kbd_data(sc_kbdc) != KBD_ECHO) {
+ empty_both_buffers(sc_kbdc, 10);
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+ if (bootverbose)
+ printf("sc%d: failed to get response from the keyboard.\n",
+ unit);
+ goto fail;
+ }
+ } else {
+ /* reset keyboard hardware */
+ if (!reset_kbd(sc_kbdc)) {
+ /* KEYBOARD ERROR
+ * Keyboard reset may fail either because the keyboard doen't
+ * exist, or because the keyboard doesn't pass the self-test,
+ * or the keyboard controller on the motherboard and the keyboard
+ * somehow fail to shake hands. It is just possible, particularly
+ * in the last case, that the keyoard controller may be left
+ * in a hung state. test_controller() and test_kbd_port() appear
+ * to bring the keyboard controller back (I don't know why and
+ * how, though.)
+ */
+ empty_both_buffers(sc_kbdc, 10);
+ test_controller(sc_kbdc);
+ test_kbd_port(sc_kbdc);
+ /* We could disable the keyboard port and interrupt... but,
+ * the keyboard may still exist (see above).
+ */
+ if (bootverbose)
+ printf("sc%d: failed to reset the keyboard.\n", unit);
+ goto fail;
+ }
+ }
+
+ /*
+ * Allow us to set the XT_KEYBD flag in UserConfig so that keyboards
+ * such as those on the IBM ThinkPad laptop computers can be used
+ * with the standard console driver.
+ */
+ if (codeset == 1) {
+ if (send_kbd_command_and_data(
+ sc_kbdc, KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) {
+ /* XT kbd doesn't need scan code translation */
+ c &= ~KBD_TRANSLATION;
+ } else {
+ /* KEYBOARD ERROR
+ * The XT kbd isn't usable unless the proper scan code set
+ * is selected.
+ */
+ printf("sc%d: unable to set the XT keyboard mode.\n", unit);
+ goto fail;
+ }
+ }
+ /* enable the keyboard port and intr. */
+ if (!set_controller_command_byte(sc_kbdc,
+ KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK,
+ (c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK))
+ | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
+ /* CONTROLLER ERROR
+ * This is serious; we are left with the disabled keyboard intr.
+ */
+ printf("sc%d: unable to enable the keyboard port and intr.\n", unit);
+ goto fail;
+ }
+
+ /* Get the ID of the keyboard, if any */
+ empty_kbd_buffer(sc_kbdc, 5);
+ res = send_kbd_command(sc_kbdc, KBDC_SEND_DEV_ID);
+ if (res == KBD_ACK) {
+ /* 10ms delay */
+ DELAY(10000);
+ id = (read_kbd_data(sc_kbdc) << 8) | read_kbd_data(sc_kbdc);
+ if (bootverbose)
+ printf("sc%d: keyboard device ID: %04x\n", unit, id);
}
- kbd = kbd_get_keyboard(keyboard); /* shouldn't fail */
+ kbdc_set_device_mask(sc_kbdc, m | KBD_KBD_CONTROL_BITS),
+ kbdc_lock(sc_kbdc, FALSE);
+#endif /* !PC98 */
return TRUE;
+#ifndef PC98
+fail:
+ if (c != -1)
+ /* try to restore the command byte as before, if possible */
+ set_controller_command_byte(sc_kbdc, 0xff, c);
+ kbdc_set_device_mask(sc_kbdc,
+ (flags & DETECT_KBD) ? m : m | KBD_KBD_CONTROL_BITS);
+ kbdc_lock(sc_kbdc, FALSE);
+ return FALSE;
+#endif /* !PC98 */
}
#if NAPM > 0
static int
scresume(void *dummy)
{
- if (kbd != NULL)
- kbd_clear_state(kbd);
- return 0;
+ shfts = ctls = alts = agrs = metas = accents = 0;
+ return 0;
}
#endif
@@ -584,85 +825,117 @@ static int
scattach(struct isa_device *dev)
{
scr_stat *scp;
-#if defined(VESA) && defined(VM86)
- video_info_t info;
-#endif
dev_t cdev = makedev(CDEV_MAJOR, 0);
+ char *p;
#ifdef DEVFS
int vc;
#endif
scinit();
+ flags = dev->id_flags;
+ if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode))
+ flags &= ~CHAR_CURSOR;
+
scp = console[0];
- sc_flags = dev->id_flags;
- if (!ISFONTAVAIL(scp->adp->va_flags))
- sc_flags &= ~CHAR_CURSOR;
+
+ if (crtc_type == KD_VGA) {
+ cut_buffer_size = scp->xsize * scp->ysize + 1;
+ cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT);
+ if (cut_buffer != NULL)
+ cut_buffer[0] = '\0';
+ }
+
+ scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
+ M_DEVBUF, M_NOWAIT);
+#ifdef PC98
+ scp->atr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
+ M_DEVBUF, M_NOWAIT);
+#endif
/* copy temporary buffer to final buffer */
- scp->scr_buf = NULL;
+ bcopy(sc_buffer, scp->scr_buf, scp->xsize * scp->ysize * sizeof(u_short));
+
#ifdef PC98
- scp->atr_buf = NULL;
+ bcopy(Atrat, scp->atr_buf, scp->xsize * scp->ysize * sizeof(u_short));
#endif
- sc_alloc_scr_buffer(scp, FALSE, FALSE);
- bcopy(sc_buffer, scp->scr_buf, scp->xsize*scp->ysize*sizeof(u_short));
+ scp->cursor_pos = scp->cursor_oldpos =
+ scp->scr_buf + scp->xpos + scp->ypos * scp->xsize;
#ifdef PC98
- bcopy(Atrat, scp->atr_buf, scp->xsize*scp->ysize*sizeof(u_short));
+ scp->cursor_atr =
+ scp->atr_buf + scp->xpos + scp->ypos * scp->xsize;
#endif
-
- /* cut buffer is available only when the mouse pointer is used */
- if (ISMOUSEAVAIL(scp->adp->va_flags))
- sc_alloc_cut_buffer(scp, FALSE);
+ scp->mouse_pos = scp->mouse_oldpos =
+ scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
+ scp->mouse_xpos/8);
/* initialize history buffer & pointers */
- sc_alloc_history_buffer(scp, sc_history_size, 0, FALSE);
-
-#if defined(VESA) && defined(VM86)
- if ((sc_flags & VESA800X600)
- && ((*vidsw[scp->ad]->get_info)(scp->adp, M_VESA_800x600, &info) == 0)) {
-#if NSPLASH > 0
- splash_term(scp->adp);
-#endif
- sc_set_graphics_mode(scp, NULL, M_VESA_800x600);
- sc_set_pixel_mode(scp, NULL, COL, ROW, 16);
- initial_video_mode = M_VESA_800x600;
-#if NSPLASH > 0
- /* put up the splash again! */
- splash_init(scp->adp, scsplash_callback);
+ scp->history_head = scp->history_pos =
+ (u_short *)malloc(scp->history_size*sizeof(u_short),
+ M_DEVBUF, M_NOWAIT);
+ if (scp->history_head != NULL)
+ bzero(scp->history_head, scp->history_size*sizeof(u_short));
+ scp->history = scp->history_head;
+#ifdef PC98
+ scp->his_atr_head = scp->his_atr_pos =
+ (u_short *)malloc(scp->history_size*sizeof(u_short),
+ M_DEVBUF, M_NOWAIT);
+ if (scp->his_atr_head != NULL)
+ bzero(scp->his_atr_head, scp->history_size*sizeof(u_short));
+ scp->his_atr = scp->his_atr_pos;
#endif
- }
-#endif /* VESA && VM86 */
/* initialize cursor stuff */
- if (!ISGRAPHSC(scp))
+ if (!(scp->status & UNKNOWN_MODE))
draw_cursor_image(scp);
/* get screen update going */
scrn_timer((void *)TRUE);
- /* set up the keyboard */
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&scp->kbd_mode);
- update_kbd_state(scp->status, LOCK_MASK);
+ update_leds(scp->status);
- if (bootverbose) {
- printf("sc%d:", dev->id_unit);
- if (adapter >= 0)
- printf(" fb%d", adapter);
- if (keyboard >= 0)
- printf(" kbd%d", keyboard);
- printf("\n");
+#ifndef PC98
+ if ((crtc_type == KD_VGA) && bootverbose) {
+ printf("sc%d: BIOS video mode:%d\n", dev->id_unit, bios_video_mode);
+ printf("sc%d: VGA registers upon power-up\n", dev->id_unit);
+ dump_vgaregs(vgaregs);
+ printf("sc%d: video mode:%d\n", dev->id_unit, scp->mode);
+ printf("sc%d: VGA registers in BIOS for mode:%d\n",
+ dev->id_unit, scp->mode);
+ dump_vgaregs(vgaregs2);
+ p = get_mode_param(scp, scp->mode);
+ if (p != NULL) {
+ printf("sc%d: VGA registers to be used for mode:%d\n",
+ dev->id_unit, scp->mode);
+ dump_vgaregs(p);
+ }
+ printf("sc%d: rows_offset:%d\n", dev->id_unit, rows_offset);
}
+ if ((crtc_type == KD_VGA) && !VESA_MODE(bios_video_mode)
+ && (video_mode_ptr == NULL))
+ printf("sc%d: WARNING: video mode switching is only partially supported\n",
+ dev->id_unit);
+#endif
+
printf("sc%d: ", dev->id_unit);
- switch(scp->adp->va_type) {
+ switch(crtc_type) {
#ifdef PC98
case KD_PC98:
printf(" <text mode>");
break;
#else
case KD_VGA:
- printf("VGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono");
+ if (VESA_MODE(bios_video_mode))
+ printf("Graphics display (VESA mode = 0x%x)", bios_video_mode);
+ else if (crtc_addr == MONO_BASE)
+ printf("VGA mono");
+ else
+ printf("VGA color");
break;
case KD_EGA:
- printf("EGA %s", (scp->adp->va_flags & V_ADP_COLOR) ? "color" : "mono");
+ if (crtc_addr == MONO_BASE)
+ printf("EGA mono");
+ else
+ printf("EGA color");
break;
case KD_CGA:
printf("CGA");
@@ -670,11 +943,11 @@ scattach(struct isa_device *dev)
case KD_MONO:
case KD_HERCULES:
default:
- printf("MDA/Hercules");
+ printf("MDA/hercules");
break;
#endif /* PC98 */
}
- printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, sc_flags);
+ printf(" <%d virtual consoles, flags=0x%x>\n", MAXCONS, flags);
#if NAPM > 0
scp->r_hook.ah_fun = scresume;
@@ -720,8 +993,6 @@ int
scopen(dev_t dev, int flag, int mode, struct proc *p)
{
struct tty *tp = scdevtotty(dev);
- keyarg_t key;
- int s;
if (!tp)
return(ENXIO);
@@ -733,9 +1004,7 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
ttychars(tp);
/* Use the current setting of the <-- key as default VERASE. */
/* If the Delete key is preferable, an stty is necessary */
- key.keynum = 0x0e; /* how do we know this magic number... XXX */
- kbd_ioctl(kbd, GIO_KEYMAPENT, (caddr_t)&key);
- tp->t_cc[VERASE] = key.key.map[0];
+ tp->t_cc[VERASE] = key_map.key[0x0e].map[0];
tp->t_iflag = TTYDEF_IFLAG;
tp->t_oflag = TTYDEF_OFLAG;
tp->t_cflag = TTYDEF_CFLAG;
@@ -745,20 +1014,12 @@ scopen(dev_t dev, int flag, int mode, struct proc *p)
(*linesw[tp->t_line].l_modem)(tp, 1);
if (minor(dev) == SC_MOUSE)
mouse_level = 0; /* XXX */
- if (minor(dev) < MAXCONS && console[minor(dev)] && scrn_blanked) {
- s = spltty();
- sc_touch_scrn_saver();
- sc_clean_up(console[minor(dev)]);
- splx(s);
- }
}
else
if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0)
return(EBUSY);
if (minor(dev) < MAXCONS && !console[minor(dev)]) {
console[minor(dev)] = alloc_scp();
- if (ISGRAPHSC(console[minor(dev)]))
- sc_set_pixel_mode(console[minor(dev)], NULL, COL, ROW, 16);
}
if (minor(dev)<MAXCONS && !tp->t_winsize.ws_col && !tp->t_winsize.ws_row) {
tp->t_winsize.ws_col = console[minor(dev)]->xsize;
@@ -776,7 +1037,7 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
if (!tp)
return(ENXIO);
if (minor(dev) < MAXCONS) {
- scp = sc_get_scr_stat(tp->t_dev);
+ scp = get_scr_stat(tp->t_dev);
if (scp->status & SWITCH_WAIT_ACQ)
wakeup((caddr_t)&scp->smode);
#if not_yet_done
@@ -795,9 +1056,9 @@ scclose(dev_t dev, int flag, int mode, struct proc *p)
if (scp->history != NULL) {
free(scp->history, M_DEVBUF);
if (scp->history_size / scp->xsize
- > imax(sc_history_size, scp->ysize))
+ > imax(SC_HISTORY_SIZE, scp->ysize))
extra_history_size += scp->history_size / scp->xsize
- - imax(sc_history_size, scp->ysize);
+ - imax(SC_HISTORY_SIZE, scp->ysize);
}
free(scp, M_DEVBUF);
console[minor(dev)] = NULL;
@@ -835,53 +1096,38 @@ scwrite(dev_t dev, struct uio *uio, int flag)
return((*linesw[tp->t_line].l_write)(tp, uio, flag));
}
-static int
-sckbdevent(keyboard_t *thiskbd, int event, void *arg)
+void
+scintr(int unit)
{
static struct tty *cur_tty;
- int c;
- size_t len;
+ int c, len;
u_char *cp;
- /* assert(thiskbd == kbd) */
-
- switch (event) {
- case KBDIO_KEYINPUT:
- break;
- case KBDIO_UNLOADING:
- kbd = NULL;
- kbd_release(thiskbd, (void *)&keyboard);
- return 0;
- default:
- return EINVAL;
- }
-
/*
* Loop while there is still input to get from the keyboard.
* I don't think this is nessesary, and it doesn't fix
* the Xaccel-2.1 keyboard hang, but it can't hurt. XXX
*/
- while ((c = scgetc(thiskbd, SCGETC_NONBLOCK)) != NOKEY) {
+ while ((c = scgetc(SCGETC_NONBLOCK)) != NOKEY) {
cur_tty = VIRTUAL_TTY(get_scr_num());
if (!(cur_tty->t_state & TS_ISOPEN))
if (!((cur_tty = CONSOLE_TTY)->t_state & TS_ISOPEN))
continue;
- switch (KEYFLAGS(c)) {
+ switch (c & 0xff00) {
case 0x0000: /* normal key */
- (*linesw[cur_tty->t_line].l_rint)(KEYCHAR(c), cur_tty);
+ (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty);
break;
case FKEY: /* function key, return string */
- cp = kbd_get_fkeystr(thiskbd, KEYCHAR(c), &len);
- if (cp != NULL) {
+ if (cp = get_fstr((u_int)c, (u_int *)&len)) {
while (len-- > 0)
- (*linesw[cur_tty->t_line].l_rint)(*cp++, cur_tty);
+ (*linesw[cur_tty->t_line].l_rint)(*cp++ & 0xFF, cur_tty);
}
break;
case MKEY: /* meta is active, prepend ESC */
(*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty);
- (*linesw[cur_tty->t_line].l_rint)(KEYCHAR(c), cur_tty);
+ (*linesw[cur_tty->t_line].l_rint)(c & 0xFF, cur_tty);
break;
case BKEY: /* backtab fixed sequence (esc [ Z) */
(*linesw[cur_tty->t_line].l_rint)(0x1b, cur_tty);
@@ -891,11 +1137,10 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
}
}
- if (cur_console->status & MOUSE_VISIBLE) {
- remove_mouse_image(cur_console);
+ if (cur_console->status & MOUSE_ENABLED) {
cur_console->status &= ~MOUSE_VISIBLE;
+ remove_mouse_image(cur_console);
}
- return 0;
}
static int
@@ -910,29 +1155,28 @@ scparam(struct tty *tp, struct termios *t)
int
scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
{
- u_int delta_ehs;
int error;
- int i;
+ u_int i;
struct tty *tp;
scr_stat *scp;
+ u_short *usp;
+#ifdef PC98
+ u_short *atr_usp;
+#endif
+ char *mp;
int s;
tp = scdevtotty(dev);
if (!tp)
return ENXIO;
- scp = sc_get_scr_stat(tp->t_dev);
+ scp = get_scr_stat(tp->t_dev);
/* If there is a user_ioctl function call that first */
if (sc_user_ioctl) {
- error = (*sc_user_ioctl)(dev, cmd, data, flag, p);
- if (error != ENOIOCTL)
+ if (error = (*sc_user_ioctl)(dev, cmd, data, flag, p))
return error;
}
- error = sc_vid_ioctl(tp, cmd, data, flag, p);
- if (error != ENOIOCTL)
- return error;
-
switch (cmd) { /* process console hardware related ioctl's */
case GIO_ATTR: /* get current attributes */
@@ -940,7 +1184,22 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case GIO_COLOR: /* is this a color console ? */
- *(int *)data = (scp->adp->va_flags & V_ADP_COLOR) ? 1 : 0;
+#ifdef PC98
+ *(int*)data = 0;
+#else
+ if (crtc_addr == COLOR_BASE)
+ *(int*)data = 1;
+ else
+ *(int*)data = 0;
+#endif
+ return 0;
+
+ case CONS_CURRENT: /* get current adapter type */
+ *(int *)data = crtc_type;
+ return 0;
+
+ case CONS_GET: /* get current video mode */
+ *(int*)data = scp->mode;
return 0;
case CONS_BLANKTIME: /* set screen saver timeout (0 = no saver) */
@@ -954,38 +1213,36 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case CONS_CURSORTYPE: /* set cursor type blink/noblink */
if ((*(int*)data) & 0x01)
- sc_flags |= BLINK_CURSOR;
+ flags |= BLINK_CURSOR;
else
- sc_flags &= ~BLINK_CURSOR;
+ flags &= ~BLINK_CURSOR;
if ((*(int*)data) & 0x02) {
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode))
return ENXIO;
- sc_flags |= CHAR_CURSOR;
+ flags |= CHAR_CURSOR;
} else
- sc_flags &= ~CHAR_CURSOR;
+ flags &= ~CHAR_CURSOR;
/*
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!ISGRAPHSC(cur_console)) {
- s = spltty();
+ if (!(cur_console->status & UNKNOWN_MODE)) {
remove_cursor_image(cur_console);
- if (sc_flags & CHAR_CURSOR)
+ if (flags & CHAR_CURSOR)
set_destructive_cursor(cur_console);
draw_cursor_image(cur_console);
- splx(s);
}
return 0;
case CONS_BELLTYPE: /* set bell type sound/visual */
if ((*(int *)data) & 0x01)
- sc_flags |= VISUAL_BELL;
+ flags |= VISUAL_BELL;
else
- sc_flags &= ~VISUAL_BELL;
+ flags &= ~VISUAL_BELL;
if ((*(int *)data) & 0x02)
- sc_flags |= QUIET_BELL;
+ flags |= QUIET_BELL;
else
- sc_flags &= ~QUIET_BELL;
+ flags &= ~QUIET_BELL;
return 0;
case CONS_HISTORY: /* set history size */
@@ -996,22 +1253,50 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
lines = imax(*(int *)data, scp->ysize);
lines0 = (scp->history != NULL) ?
scp->history_size / scp->xsize : scp->ysize;
- if (lines0 > imax(sc_history_size, scp->ysize))
- delta_ehs = lines0 - imax(sc_history_size, scp->ysize);
- else
- delta_ehs = 0;
/*
* syscons unconditionally allocates buffers upto SC_HISTORY_SIZE
* lines or scp->ysize lines, whichever is larger. A value
* greater than that is allowed, subject to extra_history_size.
*/
- if (lines > imax(sc_history_size, scp->ysize))
- if (lines - imax(sc_history_size, scp->ysize) >
- extra_history_size + delta_ehs)
- return EINVAL;
+ if (lines > imax(lines0, SC_HISTORY_SIZE) + extra_history_size)
+ return EINVAL;
if (cur_console->status & BUFFER_SAVED)
return EBUSY;
- sc_alloc_history_buffer(scp, lines, delta_ehs, TRUE);
+ usp = scp->history;
+ scp->history = NULL;
+ if (usp != NULL)
+ free(usp, M_DEVBUF);
+#ifdef PC98
+ atr_usp = scp->his_atr;
+ scp->his_atr = NULL;
+ if (atr_usp != NULL)
+ free(atr_usp, M_DEVBUF);
+#endif
+ scp->history_size = lines * scp->xsize;
+ /*
+ * extra_history_size +=
+ * (lines0 > imax(SC_HISTORY_SIZE, scp->ysize)) ?
+ * lines0 - imax(SC_HISTORY_SIZE, scp->ysize)) : 0;
+ * extra_history_size -=
+ * (lines > imax(SC_HISTORY_SIZE, scp->ysize)) ?
+ * lines - imax(SC_HISTORY_SIZE, scp->ysize)) : 0;
+ * lines0 >= ysize && lines >= ysize... Hey, the above can be
+ * reduced to the following...
+ */
+ extra_history_size +=
+ imax(lines0, SC_HISTORY_SIZE) - imax(lines, SC_HISTORY_SIZE);
+ usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
+ M_DEVBUF, M_WAITOK);
+ bzero(usp, scp->history_size * sizeof(u_short));
+ scp->history_head = scp->history_pos = usp;
+ scp->history = usp;
+#ifdef PC98
+ atr_usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
+ M_DEVBUF, M_WAITOK);
+ bzero(atr_usp, scp->history_size * sizeof(u_short));
+ scp->his_atr_head = scp->his_atr_pos = atr_usp;
+ scp->his_atr = atr_usp;
+#endif
return 0;
}
else
@@ -1021,8 +1306,9 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
case OLD_CONS_MOUSECTL:
{
/* MOUSE_BUTTON?DOWN -> MOUSE_MSC_BUTTON?UP */
- static int butmap[8] = {
- MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
+ static butmap[8] = {
+ MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON2UP
+ | MOUSE_MSC_BUTTON3UP,
MOUSE_MSC_BUTTON2UP | MOUSE_MSC_BUTTON3UP,
MOUSE_MSC_BUTTON1UP | MOUSE_MSC_BUTTON3UP,
MOUSE_MSC_BUTTON3UP,
@@ -1034,12 +1320,11 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
mouse_info_t *mouse = (mouse_info_t*)data;
mouse_info_t buf;
- /* FIXME: */
- if (!ISMOUSEAVAIL(scp->adp->va_flags))
+ if (crtc_type != KD_VGA || VESA_MODE(bios_video_mode))
return ENODEV;
if (cmd == OLD_CONS_MOUSECTL) {
- static u_char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+ static unsigned char swapb[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
old_mouse_info_t *old_mouse = (old_mouse_info_t *)data;
mouse = &buf;
@@ -1084,7 +1369,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case MOUSE_SHOW:
- if (ISTEXTSC(scp) && !(scp->status & MOUSE_ENABLED)) {
+ if (!(scp->status & MOUSE_ENABLED)) {
scp->status |= (MOUSE_ENABLED | MOUSE_VISIBLE);
scp->mouse_oldpos = scp->mouse_pos;
mark_all(scp);
@@ -1095,7 +1380,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
case MOUSE_HIDE:
- if (ISTEXTSC(scp) && (scp->status & MOUSE_ENABLED)) {
+ if (scp->status & MOUSE_ENABLED) {
scp->status &= ~(MOUSE_ENABLED | MOUSE_VISIBLE);
mark_all(scp);
return 0;
@@ -1140,7 +1425,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (mouse_status.flags == 0)
return 0;
- if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
+ if (cur_console->status & MOUSE_ENABLED)
cur_console->status |= MOUSE_VISIBLE;
if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
@@ -1185,7 +1470,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
else if (mouse->operation == MOUSE_ACTION && cut_buffer != NULL) {
/* process button presses */
if ((cur_console->mouse_buttons ^ mouse->u.data.buttons) &&
- ISTEXTSC(cur_console)) {
+ !(cur_console->status & UNKNOWN_MODE)) {
cur_console->mouse_buttons = mouse->u.data.buttons;
if (cur_console->mouse_buttons & MOUSE_BUTTON1DOWN)
mouse_cut_start(cur_console);
@@ -1222,7 +1507,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
if (mouse_status.flags == 0)
return 0;
- if (ISTEXTSC(cur_console) && (cur_console->status & MOUSE_ENABLED))
+ if (cur_console->status & MOUSE_ENABLED)
cur_console->status |= MOUSE_VISIBLE;
if ((MOUSE_TTY)->t_state & TS_ISOPEN) {
@@ -1251,7 +1536,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
break;
}
- if (!ISTEXTSC(cur_console) || (cut_buffer == NULL))
+ if ((cur_console->status & UNKNOWN_MODE) || (cut_buffer == NULL))
break;
switch (mouse->u.event.id) {
@@ -1298,7 +1583,8 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return EINVAL;
}
/* make screensaver happy */
- sc_touch_scrn_saver();
+ scsplash_stick(FALSE);
+ run_scrn_saver = FALSE;
return 0;
}
@@ -1419,9 +1705,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
ptr->mv_grfc.fore = 0; /* not supported */
ptr->mv_grfc.back = 0; /* not supported */
ptr->mv_ovscan = scp->border;
- if (scp == cur_console)
- save_kbd_state(scp);
- ptr->mk_keylock = scp->status & LOCK_MASK;
+ ptr->mk_keylock = scp->status & LOCK_KEY_MASK;
return 0;
}
return EINVAL;
@@ -1432,43 +1716,18 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case CONS_IDLE: /* see if the screen has been idle */
- /*
- * When the screen is in the GRAPHICS_MODE or UNKNOWN_MODE,
- * the user process may have been writing something on the
- * screen and syscons is not aware of it. Declare the screen
- * is NOT idle if it is in one of these modes. But there is
- * an exception to it; if a screen saver is running in the
- * graphics mode in the current screen, we should say that the
- * screen has been idle.
- */
- *(int *)data = scrn_idle
- && (!ISGRAPHSC(cur_console)
- || (cur_console->status & SAVER_RUNNING));
+ *(int *)data = (scrn_idle && !(cur_console->status & UNKNOWN_MODE));
return 0;
case CONS_SAVERMODE: /* set saver mode */
switch(*(int *)data) {
case CONS_USR_SAVER:
- /* if a LKM screen saver is running, stop it first. */
- scsplash_stick(FALSE);
+ /* if a LKM screen saver is running, it will eventually stop... */
saver_mode = *(int *)data;
- s = spltty();
-#if NSPLASH > 0
- if ((error = wait_scrn_saver_stop())) {
- splx(s);
- return error;
- }
-#endif /* NSPLASH */
- scp->status |= SAVER_RUNNING;
scsplash_stick(TRUE);
- splx(s);
break;
case CONS_LKM_SAVER:
- s = spltty();
- if ((saver_mode == CONS_USR_SAVER) && (scp->status & SAVER_RUNNING))
- scp->status &= ~SAVER_RUNNING;
saver_mode = *(int *)data;
- splx(s);
break;
default:
return EINVAL;
@@ -1487,6 +1746,279 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
splx(s);
return 0;
+#ifdef PC98
+ case SW_PC98_80x25:
+ case SW_PC98_80x30: /* PC98 TEXT MODES */
+ if (!crtc_vga)
+ return ENXIO;
+ scp->xsize = 80;
+
+ scp->status &= ~MOUSE_VISIBLE;
+ remove_cutmarking(scp);
+ s = spltty();
+ if ((error = wait_scrn_saver_stop())) {
+ splx(s);
+ return error;
+ }
+ if (scp->history != NULL)
+ i = imax(scp->history_size / scp->xsize
+ - imax(SC_HISTORY_SIZE, scp->ysize), 0);
+ else
+ i = 0;
+ switch (cmd & 0xff) {
+ case M_PC98_80x25:
+ scp->ysize = 25;
+ break;
+#ifdef LINE30
+ case M_PC98_80x30:
+ scp->ysize = LINE30_ROW;
+ break;
+#endif
+ default:
+ return EINVAL;
+ }
+#else /* IBM-PC */
+ /* VGA TEXT MODES */
+ case SW_VGA_C40x25:
+ case SW_VGA_C80x25: case SW_VGA_M80x25:
+ case SW_VGA_C80x30: case SW_VGA_M80x30:
+ case SW_VGA_C80x50: case SW_VGA_M80x50:
+ case SW_VGA_C80x60: case SW_VGA_M80x60:
+ case SW_B40x25: case SW_C40x25:
+ case SW_B80x25: case SW_C80x25:
+ case SW_ENH_B40x25: case SW_ENH_C40x25:
+ case SW_ENH_B80x25: case SW_ENH_C80x25:
+ case SW_ENH_B80x43: case SW_ENH_C80x43:
+ case SW_EGAMONO80x25:
+
+ if (crtc_type != KD_VGA)
+ return ENODEV;
+ mp = get_mode_param(scp, cmd & 0xff);
+ if (mp == NULL)
+ return ENODEV;
+
+ s = spltty();
+ if ((error = wait_scrn_saver_stop())) {
+ splx(s);
+ return error;
+ }
+
+ scp->status &= ~MOUSE_VISIBLE;
+ remove_cutmarking(scp);
+ if (scp->history != NULL)
+ i = imax(scp->history_size / scp->xsize
+ - imax(SC_HISTORY_SIZE, scp->ysize), 0);
+ else
+ i = 0;
+ switch (cmd & 0xff) {
+ case M_VGA_C80x60: case M_VGA_M80x60:
+ if (!(fonts_loaded & FONT_8)) {
+ splx(s);
+ return EINVAL;
+ }
+ /*
+ * This is a kludge to fend off scrn_update() while we
+ * muck around with scp. XXX
+ */
+ scp->status |= UNKNOWN_MODE;
+ scp->xsize = 80;
+ scp->ysize = 60;
+ scp->font_size = 8;
+ break;
+ case M_VGA_C80x50: case M_VGA_M80x50:
+ if (!(fonts_loaded & FONT_8)) {
+ splx(s);
+ return EINVAL;
+ }
+ scp->status |= UNKNOWN_MODE;
+ scp->xsize = 80;
+ scp->ysize = 50;
+ scp->font_size = 8;
+ break;
+ case M_ENH_B80x43: case M_ENH_C80x43:
+ if (!(fonts_loaded & FONT_8)) {
+ splx(s);
+ return EINVAL;
+ }
+ scp->status |= UNKNOWN_MODE;
+ scp->xsize = 80;
+ scp->ysize = 43;
+ scp->font_size = 8;
+ break;
+ case M_VGA_C80x30: case M_VGA_M80x30:
+ scp->status |= UNKNOWN_MODE;
+ scp->xsize = 80;
+ scp->ysize = 30;
+ scp->font_size = mp[2];
+ break;
+ case M_ENH_C40x25: case M_ENH_B40x25:
+ case M_ENH_C80x25: case M_ENH_B80x25:
+ case M_EGAMONO80x25:
+ if (!(fonts_loaded & FONT_14)) {
+ splx(s);
+ return EINVAL;
+ }
+ /* FALL THROUGH */
+ default:
+ if ((cmd & 0xff) > M_VGA_CG320) {
+ splx(s);
+ return EINVAL;
+ }
+ scp->status |= UNKNOWN_MODE;
+ scp->xsize = mp[0];
+ scp->ysize = mp[1] + rows_offset;
+ scp->font_size = mp[2];
+ break;
+ }
+#endif
+
+ scp->mode = cmd & 0xff;
+ scp->xpixel = scp->xsize * 8;
+ scp->ypixel = scp->ysize * scp->font_size;
+ free(scp->scr_buf, M_DEVBUF);
+ scp->scr_buf = (u_short *)
+ malloc(scp->xsize*scp->ysize*sizeof(u_short), M_DEVBUF, M_WAITOK);
+#ifdef PC98
+ free(scp->atr_buf, M_DEVBUF);
+ scp->atr_buf = (u_short *)
+ malloc(scp->xsize*scp->ysize*sizeof(u_short),M_DEVBUF, M_WAITOK);
+#endif
+ /* move the text cursor to the home position */
+ move_crsr(scp, 0, 0);
+ /* move the mouse cursor at the center of the screen */
+ scp->mouse_xpos = scp->xpixel / 2;
+ scp->mouse_ypos = scp->ypixel / 2;
+ scp->mouse_pos = scp->mouse_oldpos =
+ scp->scr_buf + (scp->mouse_ypos / scp->font_size) * scp->xsize
+ + scp->mouse_xpos / 8;
+ /* allocate a larger cut buffer if necessary */
+ if ((cut_buffer == NULL)
+ || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
+ if (cut_buffer != NULL)
+ free(cut_buffer, M_DEVBUF);
+ cut_buffer_size = scp->xsize * scp->ysize + 1;
+ cut_buffer = (char *)malloc(cut_buffer_size, M_DEVBUF, M_NOWAIT);
+ if (cut_buffer != NULL)
+ cut_buffer[0] = '\0';
+ }
+ splx(s);
+
+ usp = scp->history;
+ scp->history = NULL;
+ if (usp != NULL) {
+ free(usp, M_DEVBUF);
+ extra_history_size += i;
+ }
+#ifdef PC98
+ atr_usp = scp->his_atr;
+ scp->his_atr = NULL;
+ if (atr_usp != NULL)
+ free(atr_usp, M_DEVBUF);
+#endif
+ scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize;
+ usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
+ M_DEVBUF, M_NOWAIT);
+ if (usp != NULL)
+ bzero(usp, scp->history_size * sizeof(u_short));
+ scp->history_head = scp->history_pos = usp;
+ scp->history = usp;
+#ifdef PC98
+ atr_usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
+ M_DEVBUF, M_NOWAIT);
+ if (atr_usp != NULL)
+ bzero(atr_usp, scp->history_size * sizeof(u_short));
+ scp->his_atr_head = scp->his_atr_pos = atr_usp;
+ scp->his_atr = atr_usp;
+#endif
+ if (scp == cur_console)
+ set_mode(scp);
+ clear_screen(scp);
+ scp->status &= ~UNKNOWN_MODE;
+
+ if (tp->t_winsize.ws_col != scp->xsize
+ || tp->t_winsize.ws_row != scp->ysize) {
+ tp->t_winsize.ws_col = scp->xsize;
+ tp->t_winsize.ws_row = scp->ysize;
+ pgsignal(tp->t_pgrp, SIGWINCH, 1);
+ }
+ return 0;
+#ifndef PC98
+ /* GRAPHICS MODES */
+ case SW_BG320: case SW_BG640:
+ case SW_CG320: case SW_CG320_D: case SW_CG640_E:
+ case SW_CG640x350: case SW_ENH_CG640:
+ case SW_BG640x480: case SW_CG640x480: case SW_VGA_CG320:
+
+ if (crtc_type != KD_VGA)
+ return ENODEV;
+ mp = get_mode_param(scp, cmd & 0xff);
+ if (mp == NULL)
+ return ENODEV;
+
+ s = spltty();
+ if ((error = wait_scrn_saver_stop())) {
+ splx(s);
+ return error;
+ }
+
+ scp->status &= ~MOUSE_VISIBLE;
+ remove_cutmarking(scp);
+ scp->status |= UNKNOWN_MODE; /* graphics mode */
+ scp->mode = cmd & 0xFF;
+ scp->xpixel = mp[0] * 8;
+ scp->ypixel = (mp[1] + rows_offset) * mp[2];
+ scp->font_size = FONT_NONE;
+ /* move the mouse cursor at the center of the screen */
+ scp->mouse_xpos = scp->xpixel / 2;
+ scp->mouse_ypos = scp->ypixel / 2;
+ splx(s);
+
+ if (scp == cur_console)
+ set_mode(scp);
+ /* clear_graphics();*/
+
+ if (tp->t_winsize.ws_xpixel != scp->xpixel
+ || tp->t_winsize.ws_ypixel != scp->ypixel) {
+ tp->t_winsize.ws_xpixel = scp->xpixel;
+ tp->t_winsize.ws_ypixel = scp->ypixel;
+ pgsignal(tp->t_pgrp, SIGWINCH, 1);
+ }
+ return 0;
+
+ case SW_VGA_MODEX:
+ if (crtc_type != KD_VGA)
+ return ENODEV;
+ mp = get_mode_param(scp, cmd & 0xff);
+ if (mp == NULL)
+ return ENODEV;
+
+ s = spltty();
+ if ((error = wait_scrn_saver_stop())) {
+ splx(s);
+ return error;
+ }
+
+ scp->status &= ~MOUSE_VISIBLE;
+ remove_cutmarking(scp);
+ scp->status |= UNKNOWN_MODE; /* graphics mode */
+ scp->mode = cmd & 0xFF;
+ scp->xpixel = 320;
+ scp->ypixel = 240;
+ scp->font_size = FONT_NONE;
+ splx(s);
+
+ if (scp == cur_console)
+ set_mode(scp);
+ /* clear_graphics();*/
+ if (tp->t_winsize.ws_xpixel != scp->xpixel
+ || tp->t_winsize.ws_ypixel != scp->ypixel) {
+ tp->t_winsize.ws_xpixel = scp->xpixel;
+ tp->t_winsize.ws_ypixel = scp->ypixel;
+ pgsignal(tp->t_pgrp, SIGWINCH, 1);
+ }
+ return 0;
+#endif /* PC98 */
+
case VT_SETMODE: /* set screen switcher mode */
{
struct vt_mode *mode;
@@ -1509,7 +2041,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case VT_RELDISP: /* screen switcher ioctl */
- switch(*(int *)data) {
+ switch(*data) {
case VT_FALSE: /* user refuses to release screen, abort */
if (scp == old_scp && (scp->status & SWITCH_WAIT_REL)) {
old_scp->status &= ~SWITCH_WAIT_REL;
@@ -1549,40 +2081,32 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
for (i = 0; i < MAXCONS; i++) {
tp = VIRTUAL_TTY(i);
if (!(tp->t_state & TS_ISOPEN)) {
- *(int *)data = i + 1;
+ *data = i + 1;
return 0;
}
}
return EINVAL;
case VT_ACTIVATE: /* switch to screen *data */
- s = spltty();
- sc_clean_up(cur_console);
- splx(s);
- return switch_scr(scp, *(int *)data - 1);
+ return switch_scr(scp, (*data) - 1);
case VT_WAITACTIVE: /* wait for switch to occur */
- if (*(int *)data > MAXCONS || *(int *)data < 0)
+ if (*data > MAXCONS || *data < 0)
return EINVAL;
- s = spltty();
- error = sc_clean_up(cur_console);
- splx(s);
- if (error)
- return error;
- if (minor(dev) == *(int *)data - 1)
+ if (minor(dev) == (*data) - 1)
return 0;
- if (*(int *)data == 0) {
+ if (*data == 0) {
if (scp == cur_console)
return 0;
}
else
- scp = console[*(int *)data - 1];
+ scp = console[(*data) - 1];
while ((error=tsleep((caddr_t)&scp->smode, PZERO|PCATCH,
"waitvt", 0)) == ERESTART) ;
return error;
case VT_GETACTIVE:
- *(int *)data = get_scr_num()+1;
+ *data = get_scr_num()+1;
return 0;
case KDENABIO: /* allow io operations */
@@ -1598,37 +2122,126 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
p->p_md.md_regs->tf_eflags &= ~PSL_IOPL;
return 0;
- case KDSKBSTATE: /* set keyboard state (locks) */
- if (*(int *)data & ~LOCK_MASK)
+ case KDSETMODE: /* set current mode of this (virtual) console */
+ switch (*data) {
+ case KD_TEXT: /* switch to TEXT (known) mode */
+#ifndef PC98
+ /* restore fonts & palette ! */
+ if (crtc_type == KD_VGA) {
+ if (!VESA_MODE(scp->mode)) {
+#if 0
+ /*
+ * FONT KLUDGE
+ * Don't load fonts for now... XXX
+ */
+ if (fonts_loaded & FONT_8)
+ copy_font(LOAD, FONT_8, font_8);
+ if (fonts_loaded & FONT_14)
+ copy_font(LOAD, FONT_14, font_14);
+ if (fonts_loaded & FONT_16)
+ copy_font(LOAD, FONT_16, font_16);
+#endif
+ }
+ load_palette(palette);
+ }
+
+ /* move hardware cursor out of the way */
+ outb(crtc_addr, 14);
+ outb(crtc_addr + 1, 0xff);
+ outb(crtc_addr, 15);
+ outb(crtc_addr + 1, 0xff);
+
+ /* FALL THROUGH */
+#endif
+ case KD_TEXT1: /* switch to TEXT (known) mode */
+ s = spltty();
+ if ((error = wait_scrn_saver_stop())) {
+ splx(s);
+ return error;
+ }
+ scp->status &= ~MOUSE_VISIBLE;
+ remove_cutmarking(scp);
+ scp->status |= UNKNOWN_MODE;
+ splx(s);
+ /* no restore fonts & palette */
+#ifdef PC98
+ scp->status &= ~UNKNOWN_MODE;
+#else
+ if (crtc_type == KD_VGA)
+#endif
+ set_mode(scp);
+ scp->status &= ~UNKNOWN_MODE;
+ clear_screen(scp);
+ return 0;
+
+ case KD_GRAPHICS: /* switch to GRAPHICS (unknown) mode */
+ s = spltty();
+ if ((error = wait_scrn_saver_stop())) {
+ splx(s);
+ return error;
+ }
+ scp->status &= ~MOUSE_VISIBLE;
+ remove_cutmarking(scp);
+ scp->status |= UNKNOWN_MODE;
+#ifdef PC98
+ set_mode(scp);
+#endif
+ splx(s);
+ return 0;
+ default:
return EINVAL;
- scp->status &= ~LOCK_MASK;
- scp->status |= *(int *)data;
+ }
+ /* NOT REACHED */
+
+ case KDGETMODE: /* get current mode of this (virtual) console */
+ *data = (scp->status & UNKNOWN_MODE) ? KD_GRAPHICS : KD_TEXT;
+ return 0;
+
+ case KDSBORDER: /* set border color of this (virtual) console */
+ scp->border = *data;
if (scp == cur_console)
- update_kbd_state(scp->status, LOCK_MASK);
+ set_border(scp->border);
return 0;
+ case KDSKBSTATE: /* set keyboard state (locks) */
+ if (*data >= 0 && *data <= LOCK_KEY_MASK) {
+ scp->status &= ~LOCK_KEY_MASK;
+ scp->status |= *data;
+ if (scp == cur_console)
+ update_leds(scp->status);
+ return 0;
+ }
+ return EINVAL;
+
case KDGKBSTATE: /* get keyboard state (locks) */
- if (scp == cur_console)
- save_kbd_state(scp);
- *(int *)data = scp->status & LOCK_MASK;
+ *data = scp->status & LOCK_KEY_MASK;
return 0;
case KDSETRAD: /* set keyboard repeat & delay rates */
- if (*(int *)data & ~0x7f)
+#ifndef PC98
+ if (*data & 0x80)
return EINVAL;
- error = kbd_ioctl(kbd, KDSETRAD, data);
- if (error == ENOIOCTL)
- error = ENODEV;
- return error;
+ if (sc_kbdc != NULL)
+ set_keyboard(KBDC_SET_TYPEMATIC, *data);
+#endif
+ return 0;
case KDSKBMODE: /* set keyboard mode */
- switch (*(int *)data) {
- case K_XLATE: /* switch to XLT ascii mode */
+ switch (*data) {
case K_RAW: /* switch to RAW scancode mode */
+ scp->status &= ~KBD_CODE_MODE;
+ scp->status |= KBD_RAW_MODE;
+ return 0;
+
case K_CODE: /* switch to CODE mode */
- scp->kbd_mode = *(int *)data;
- if (scp == cur_console)
- kbd_ioctl(kbd, cmd, data);
+ scp->status &= ~KBD_RAW_MODE;
+ scp->status |= KBD_CODE_MODE;
+ return 0;
+
+ case K_XLATE: /* switch to XLT ascii mode */
+ if (scp == cur_console && scp->status & KBD_RAW_MODE)
+ shfts = ctls = alts = agrs = metas = accents = 0;
+ scp->status &= ~(KBD_RAW_MODE | KBD_CODE_MODE);
return 0;
default:
return EINVAL;
@@ -1636,15 +2249,10 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
/* NOT REACHED */
case KDGKBMODE: /* get keyboard mode */
- *(int *)data = scp->kbd_mode;
+ *data = (scp->status & KBD_RAW_MODE) ? K_RAW :
+ ((scp->status & KBD_CODE_MODE) ? K_CODE : K_XLATE);
return 0;
- case KDGKBINFO:
- error = kbd_ioctl(kbd, cmd, data);
- if (error == ENOIOCTL)
- error = ENODEV;
- return error;
-
case KDMKTONE: /* sound the bell */
if (*(int*)data)
do_bell(scp, (*(int*)data)&0xffff,
@@ -1696,74 +2304,45 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return 0;
case KDGKBTYPE: /* get keyboard type */
- error = kbd_ioctl(kbd, cmd, data);
- if (error == ENOIOCTL) {
- /* always return something? XXX */
- *(int *)data = 0;
- }
+ *data = 0; /* type not known (yet) */
return 0;
case KDSETLED: /* set keyboard LED status */
- if (*(int *)data & ~LED_MASK) /* FIXME: LOCK_MASK? */
- return EINVAL;
- scp->status &= ~LED_MASK;
- scp->status |= *(int *)data;
- if (scp == cur_console)
- update_kbd_leds(scp->status);
- return 0;
+ if (*data >= 0 && *data <= LED_MASK) {
+ scp->status &= ~LED_MASK;
+ scp->status |= *data;
+ if (scp == cur_console)
+ update_leds(scp->status);
+ return 0;
+ }
+ return EINVAL;
case KDGETLED: /* get keyboard LED status */
- if (scp == cur_console)
- save_kbd_state(scp);
- *(int *)data = scp->status & LED_MASK;
+ *data = scp->status & LED_MASK;
return 0;
- case CONS_SETKBD: /* set the new keyboard */
- {
- keyboard_t *newkbd;
-
- s = spltty();
- newkbd = kbd_get_keyboard(*(int *)data);
- if (newkbd == NULL) {
- splx(s);
- return EINVAL;
- }
- error = 0;
- if (kbd != newkbd) {
- i = kbd_allocate(newkbd->kb_name, newkbd->kb_unit,
- (void *)&keyboard, sckbdevent, NULL);
- /* i == newkbd->kb_index */
- if (i >= 0) {
- if (kbd != NULL) {
- save_kbd_state(cur_console);
- kbd_release(kbd, (void *)&keyboard);
- }
- kbd = kbd_get_keyboard(i); /* kbd == newkbd */
- keyboard = i;
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
- update_kbd_state(cur_console->status, LOCK_MASK);
- } else {
- error = EPERM; /* XXX */
- }
- }
- splx(s);
- return error;
+ case GETFKEY: /* get functionkey string */
+ if (*(u_short*)data < n_fkey_tab) {
+ fkeyarg_t *ptr = (fkeyarg_t*)data;
+ bcopy(&fkey_tab[ptr->keynum].str, ptr->keydef,
+ fkey_tab[ptr->keynum].len);
+ ptr->flen = fkey_tab[ptr->keynum].len;
+ return 0;
}
+ else
+ return EINVAL;
- case CONS_RELKBD: /* release the current keyboard */
- s = spltty();
- error = 0;
- if (kbd != NULL) {
- save_kbd_state(cur_console);
- error = kbd_release(kbd, (void *)&keyboard);
- if (error == 0) {
- kbd = NULL;
- keyboard = -1;
- }
+ case SETFKEY: /* set functionkey string */
+ if (*(u_short*)data < n_fkey_tab) {
+ fkeyarg_t *ptr = (fkeyarg_t*)data;
+ bcopy(ptr->keydef, &fkey_tab[ptr->keynum].str,
+ min(ptr->flen, MAXFK));
+ fkey_tab[ptr->keynum].len = min(ptr->flen, MAXFK);
+ return 0;
}
- splx(s);
- return error;
-
+ else
+ return EINVAL;
+
case GIO_SCRNMAP: /* get output translation table */
bcopy(&scr_map, data, sizeof(scr_map));
return 0;
@@ -1774,19 +2353,36 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
scr_rmap[scr_map[i]] = i;
return 0;
- case GIO_KEYMAP: /* get keyboard translation table */
- case PIO_KEYMAP: /* set keyboard translation table */
- case GIO_DEADKEYMAP: /* get accent key translation table */
- case PIO_DEADKEYMAP: /* set accent key translation table */
- case GETFKEY: /* get function key string */
- case SETFKEY: /* set function key string */
- error = kbd_ioctl(kbd, cmd, data);
- if (error == ENOIOCTL)
- error = ENODEV;
- return error;
+ case GIO_KEYMAP: /* get keyboard translation table */
+ bcopy(&key_map, data, sizeof(key_map));
+ return 0;
+
+ case PIO_KEYMAP: /* set keyboard translation table */
+ accents = 0;
+ bzero(&accent_map, sizeof(accent_map));
+ bcopy(data, &key_map, sizeof(key_map));
+ return 0;
+
+ case GIO_DEADKEYMAP: /* get accent key translation table */
+ bcopy(&accent_map, data, sizeof(accent_map));
+ return 0;
+
+ case PIO_DEADKEYMAP: /* set accent key translation table */
+ accents = 0;
+ bcopy(data, &accent_map, sizeof(accent_map));
+ return 0;
+#ifdef PC98
+ case PIO_FONT8x8: /* set 8x8 dot font */
+ case GIO_FONT8x8: /* get 8x8 dot font */
+ case PIO_FONT8x14: /* set 8x14 dot font */
+ case GIO_FONT8x14: /* get 8x14 dot font */
+ case PIO_FONT8x16: /* set 8x16 dot font */
+ case GIO_FONT8x16: /* get 8x16 dot font */
+ return ENXIO;
+#else
case PIO_FONT8x8: /* set 8x8 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (crtc_type != KD_VGA)
return ENXIO;
bcopy(data, font_8, 8*256);
fonts_loaded |= FONT_8;
@@ -1795,12 +2391,17 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x8.
*/
- if (ISTEXTSC(cur_console) && (cur_console->font_size < 14))
- copy_font(cur_console, LOAD, 8, font_8);
+ if (!VESA_MODE(cur_console->mode)
+ && !(cur_console->status & UNKNOWN_MODE)
+ && (cur_console->font_size < 14)) {
+ copy_font(LOAD, FONT_8, font_8);
+ if (flags & CHAR_CURSOR)
+ set_destructive_cursor(cur_console);
+ }
return 0;
case GIO_FONT8x8: /* get 8x8 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (crtc_type != KD_VGA)
return ENXIO;
if (fonts_loaded & FONT_8) {
bcopy(font_8, data, 8*256);
@@ -1810,7 +2411,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return ENXIO;
case PIO_FONT8x14: /* set 8x14 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (crtc_type != KD_VGA)
return ENXIO;
bcopy(data, font_14, 14*256);
fonts_loaded |= FONT_14;
@@ -1819,13 +2420,17 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x14.
*/
- if (ISTEXTSC(cur_console)
- && (cur_console->font_size >= 14) && (cur_console->font_size < 16))
- copy_font(cur_console, LOAD, 14, font_14);
+ if (!VESA_MODE(cur_console->mode)
+ && !(cur_console->status & UNKNOWN_MODE)
+ && (cur_console->font_size >= 14) && (cur_console->font_size < 16)) {
+ copy_font(LOAD, FONT_14, font_14);
+ if (flags & CHAR_CURSOR)
+ set_destructive_cursor(cur_console);
+ }
return 0;
case GIO_FONT8x14: /* get 8x14 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (crtc_type != KD_VGA)
return ENXIO;
if (fonts_loaded & FONT_14) {
bcopy(font_14, data, 14*256);
@@ -1835,7 +2440,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
return ENXIO;
case PIO_FONT8x16: /* set 8x16 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (crtc_type != KD_VGA)
return ENXIO;
bcopy(data, font_16, 16*256);
fonts_loaded |= FONT_16;
@@ -1844,12 +2449,17 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* Always use the font page #0. XXX
* Don't load if the current font size is not 8x16.
*/
- if (ISTEXTSC(cur_console) && (cur_console->font_size >= 16))
- copy_font(cur_console, LOAD, 16, font_16);
+ if (!VESA_MODE(cur_console->mode)
+ && !(cur_console->status & UNKNOWN_MODE)
+ && (cur_console->font_size >= 16)) {
+ copy_font(LOAD, FONT_16, font_16);
+ if (flags & CHAR_CURSOR)
+ set_destructive_cursor(cur_console);
+ }
return 0;
case GIO_FONT8x16: /* get 8x16 dot font */
- if (!ISFONTAVAIL(scp->adp->va_flags))
+ if (crtc_type != KD_VGA)
return ENXIO;
if (fonts_loaded & FONT_16) {
bcopy(font_16, data, 16*256);
@@ -1857,6 +2467,7 @@ scioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
}
else
return ENXIO;
+#endif /* PC98 */
#ifdef PC98
case ADJUST_CLOCK: /* /dev/rtc for 98note resume */
@@ -1882,7 +2493,7 @@ scstart(struct tty *tp)
struct clist *rbp;
int s, len;
u_char buf[PCBURST];
- scr_stat *scp = sc_get_scr_stat(tp->t_dev);
+ scr_stat *scp = get_scr_stat(tp->t_dev);
if (scp->status & SLKED || blink_in_progress)
return; /* XXX who repeats the call when the above flags are cleared? */
@@ -1922,7 +2533,7 @@ scmousestart(struct tty *tp)
splx(s);
}
-static void
+void
sccnprobe(struct consdev *cp)
{
struct isa_device *dvp;
@@ -1936,59 +2547,35 @@ sccnprobe(struct consdev *cp)
return;
}
- if (!scvidprobe(dvp->id_unit, dvp->id_flags, TRUE)) {
+ if (!scvidprobe(dvp->id_unit, dvp->id_flags)) {
cp->cn_pri = CN_DEAD;
return;
}
- sckbdprobe(dvp->id_unit, dvp->id_flags, TRUE);
/* initialize required fields */
cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
cp->cn_pri = CN_INTERNAL;
+
+ sc_kbdc = kbdc_open(sc_port);
}
-static void
+void
sccninit(struct consdev *cp)
{
scinit();
}
-static void
+void
sccnputc(dev_t dev, int c)
{
u_char buf[1];
+ int s;
scr_stat *scp = console[0];
term_stat save = scp->term;
- u_short *p;
- int s;
- int i;
-
- if (scp == cur_console && scp->status & SLKED) {
- scp->status &= ~SLKED;
- update_kbd_state(scp->status, SLKED);
- if (cur_console->status & BUFFER_SAVED) {
- p = cur_console->history_save;
- for (i = 0; i < cur_console->ysize; ++i) {
- bcopy(p, cur_console->scr_buf + (cur_console->xsize*i),
- cur_console->xsize*sizeof(u_short));
- p += cur_console->xsize;
- if (p + cur_console->xsize
- > cur_console->history + cur_console->history_size)
- p = cur_console->history;
- }
- cur_console->status &= ~BUFFER_SAVED;
- cur_console->history_head = cur_console->history_save;
- cur_console->status |= CURSOR_ENABLED;
- mark_all(cur_console);
- }
-#if 1 /* XXX */
- scstart(VIRTUAL_TTY(get_scr_num()));
-#endif
- }
scp->term = kernel_console;
current_default = &kernel_default;
- if (scp == cur_console && !ISGRAPHSC(scp))
+ if (scp == cur_console && !(scp->status & UNKNOWN_MODE))
remove_cursor_image(scp);
buf[0] = c;
ansi_put(scp, buf, 1);
@@ -1996,71 +2583,43 @@ sccnputc(dev_t dev, int c)
current_default = &user_default;
scp->term = save;
- s = spltty(); /* block sckbdevent and scrn_timer */
+ s = spltty(); /* block scintr and scrn_timer */
sccnupdate(scp);
splx(s);
}
-static int
+int
sccngetc(dev_t dev)
{
- return sccngetch(0);
-}
-
-static int
-sccncheckc(dev_t dev)
-{
- return sccngetch(SCGETC_NONBLOCK);
-}
-
-static int
-sccngetch(int flags)
-{
- int cur_mode;
- int s = spltty(); /* block sckbdevent and scrn_timer while we poll */
+ int s = spltty(); /* block scintr and scrn_timer while we poll */
int c;
/*
* Stop the screen saver and update the screen if necessary.
* What if we have been running in the screen saver code... XXX
*/
- sc_touch_scrn_saver();
+ scsplash_stick(FALSE);
+ run_scrn_saver = FALSE;
sccnupdate(cur_console);
- if (kbd == NULL) {
- splx(s);
- return -1;
- }
-
- /*
- * Make sure the keyboard is accessible even when the kbd device
- * driver is disabled.
- */
- kbd_enable(kbd);
+ c = scgetc(SCGETC_CN);
+ splx(s);
+ return(c);
+}
- /* we shall always use the keyboard in the XLATE mode here */
- cur_mode = cur_console->kbd_mode;
- cur_console->kbd_mode = K_XLATE;
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
+int
+sccncheckc(dev_t dev)
+{
+ int s = spltty(); /* block scintr and scrn_timer while we poll */
+ int c;
- c = scgetc(kbd, SCGETC_CN | flags);
+ scsplash_stick(FALSE);
+ run_scrn_saver = FALSE;
+ sccnupdate(cur_console);
- cur_console->kbd_mode = cur_mode;
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&cur_console->kbd_mode);
- kbd_disable(kbd);
+ c = scgetc(SCGETC_CN | SCGETC_NONBLOCK);
splx(s);
-
- switch (KEYFLAGS(c)) {
- case 0: /* normal char */
- return KEYCHAR(c);
- case FKEY: /* function key */
- return c; /* XXX */
- case NOKEY:
- case ERRKEY:
- default:
- return -1;
- }
- /* NOT REACHED */
+ return(c == NOKEY ? -1 : c); /* c == -1 can't happen */
}
static void
@@ -2071,28 +2630,25 @@ sccnupdate(scr_stat *scp)
if (font_loading_in_progress)
return;
- if (panicstr || shutdown_in_progress) {
- sc_touch_scrn_saver();
- } else if (scp != cur_console) {
- return;
+ if (panicstr) {
+ scsplash_stick(FALSE);
+ run_scrn_saver = FALSE;
}
-
if (!run_scrn_saver)
scrn_idle = FALSE;
-#if NSPLASH > 0
if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked)
+ if (scrn_blanked > 0)
stop_scrn_saver(current_saver);
-#endif /* NSPLASH */
+
if (scp != cur_console || blink_in_progress || switch_in_progress)
return;
- if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
+ if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0)
scrn_update(scp, TRUE);
}
-scr_stat
-*sc_get_scr_stat(dev_t dev)
+static scr_stat
+*get_scr_stat(dev_t dev)
{
int unit = minor(dev);
@@ -2128,10 +2684,35 @@ scrn_timer(void *arg)
}
s = spltty();
+ /*
+ * With release 2.1 of the Xaccel server, the keyboard is left
+ * hanging pretty often. Apparently an interrupt from the
+ * keyboard is lost, and I don't know why (yet).
+ * This ugly hack calls scintr if input is ready for the keyboard
+ * and conveniently hides the problem. XXX
+ */
+ /* Try removing anything stuck in the keyboard controller; whether
+ * it's a keyboard scan code or mouse data. `scintr()' doesn't
+ * read the mouse data directly, but `kbdio' routines will, as a
+ * side effect.
+ */
+ if (kbdc_lock(sc_kbdc, TRUE)) {
+ /*
+ * We have seen the lock flag is not set. Let's reset the flag early;
+ * otherwise `update_led()' failes which may want the lock
+ * during `scintr()'.
+ */
+ kbdc_lock(sc_kbdc, FALSE);
+ if (kbdc_data_ready(sc_kbdc))
+ scintr(0);
+ }
+
/* should we stop the screen saver? */
getmicrouptime(&tv);
- if (panicstr || shutdown_in_progress)
- sc_touch_scrn_saver();
+ if (panicstr || shutdown_in_progress) {
+ scsplash_stick(FALSE);
+ run_scrn_saver = FALSE;
+ }
if (run_scrn_saver) {
scrn_idle = (tv.tv_sec > scrn_time_stamp + scrn_blank_time);
} else {
@@ -2140,11 +2721,10 @@ scrn_timer(void *arg)
if (scrn_blank_time > 0)
run_scrn_saver = TRUE;
}
-#if NSPLASH > 0
if ((saver_mode != CONS_LKM_SAVER) || !scrn_idle)
- if (scrn_blanked)
+ if (scrn_blanked > 0)
stop_scrn_saver(current_saver);
-#endif /* NSPLASH */
+
/* should we just return ? */
if (blink_in_progress || switch_in_progress) {
if (arg)
@@ -2155,12 +2735,12 @@ scrn_timer(void *arg)
/* Update the screen */
scp = cur_console;
- if (!ISGRAPHSC(scp) && !(scp->status & SAVER_RUNNING))
+ if ((scp->status & UNKNOWN_MODE) == 0 && scrn_blanked <= 0)
scrn_update(scp, TRUE);
/* should we activate the screen saver? */
if ((saver_mode == CONS_LKM_SAVER) && scrn_idle)
- if (!ISGRAPHSC(scp) || scrn_blanked)
+ if ((scp->status & UNKNOWN_MODE) == 0 || scrn_blanked > 0)
(*current_saver)(TRUE);
if (arg)
@@ -2228,7 +2808,7 @@ scrn_update(scr_stat *scp, int show_cursor)
draw_cursor_image(scp);
} else {
/* if its a blinking cursor, we may have to update it */
- if (sc_flags & BLINK_CURSOR)
+ if (flags & BLINK_CURSOR)
draw_cursor_image(scp);
}
}
@@ -2242,96 +2822,25 @@ scrn_update(scr_stat *scp, int show_cursor)
scp->start = scp->xsize*scp->ysize - 1;
}
-#if NSPLASH > 0
-
-static int
-scsplash_callback(int event)
-{
- int error;
-
- switch (event) {
- case SPLASH_INIT:
- scrn_saver_failed = FALSE;
- if (add_scrn_saver(scsplash_saver) == 0) {
- run_scrn_saver = TRUE;
- if (cold && !(boothowto & (RB_VERBOSE | RB_CONFIG))) {
- scsplash_stick(TRUE);
- (*current_saver)(TRUE);
- }
- }
- return 0;
-
- case SPLASH_TERM:
- if (current_saver == scsplash_saver) {
- scsplash_stick(FALSE);
- error = remove_scrn_saver(scsplash_saver);
- if (error)
- return error;
- }
- return 0;
-
- default:
- return EINVAL;
- }
-}
-
-static void
-scsplash_saver(int show)
-{
- static int busy = FALSE;
- scr_stat *scp;
-
- if (busy)
- return;
- busy = TRUE;
-
- scp = cur_console;
- if (show) {
- if (!scrn_saver_failed) {
- if (!scrn_blanked)
- set_scrn_saver_mode(scp, -1, NULL, 0);
- switch (splash(scp->adp, TRUE)) {
- case 0: /* succeeded */
- scrn_blanked = TRUE;
- break;
- case EAGAIN: /* try later */
- restore_scrn_saver_mode(scp, FALSE);
- break;
- default:
- scrn_saver_failed = TRUE;
- scsplash_stick(FALSE);
- printf("scsplash_saver(): failed to put up the image\n");
- restore_scrn_saver_mode(scp, TRUE);
- break;
- }
- }
- } else if (!sticky_splash) {
- if (scrn_blanked && (splash(scp->adp, FALSE) == 0)) {
- restore_scrn_saver_mode(scp, TRUE);
- scrn_blanked = FALSE;
- }
- }
- busy = FALSE;
-}
-
-static int
+int
add_scrn_saver(void (*this_saver)(int))
{
- int error;
-
- if (current_saver != none_saver) {
- error = remove_scrn_saver(current_saver);
- if (error)
- return error;
+#ifdef SC_SPLASH_SCREEN
+ if (current_saver == scsplash) {
+ scsplash_stick(FALSE);
+ stop_scrn_saver(scsplash);
}
+#endif
- run_scrn_saver = FALSE;
- saver_mode = CONS_LKM_SAVER;
+ if (current_saver != default_saver)
+ return EBUSY;
current_saver = this_saver;
+ saver_mode = CONS_LKM_SAVER;
+ run_scrn_saver = (scrn_blank_time > 0);
return 0;
}
-static int
+int
remove_scrn_saver(void (*this_saver)(int))
{
if (current_saver != this_saver)
@@ -2344,72 +2853,14 @@ remove_scrn_saver(void (*this_saver)(int))
* before stopping the current saver, rather than blocking by `splXX()'.
*/
current_saver = none_saver;
- if (scrn_blanked)
+ if (scrn_blanked > 0)
stop_scrn_saver(this_saver);
- return (scrn_blanked ? EBUSY : 0);
-}
-
-static int
-set_scrn_saver_mode(scr_stat *scp, int mode, u_char *pal, int border)
-{
- int s;
-
- /* assert(scp == cur_console) */
- s = spltty();
- scp->splash_save_mode = scp->mode;
- scp->splash_save_status = scp->status & (GRAPHICS_MODE | PIXEL_MODE);
- scp->status &= ~(GRAPHICS_MODE | PIXEL_MODE);
- scp->status |= (UNKNOWN_MODE | SAVER_RUNNING);
- splx(s);
- if (mode < 0)
- return 0;
- scp->mode = mode;
- if (set_mode(scp) == 0) {
- if (scp->adp->va_mode_flags & V_INFO_GRAPHICS)
- scp->status |= GRAPHICS_MODE;
- if (pal != NULL)
- load_palette(scp->adp, pal);
- set_border(scp, border);
- return 0;
- } else {
- s = spltty();
- scp->mode = scp->splash_save_mode;
- scp->status &= ~(UNKNOWN_MODE | SAVER_RUNNING);
- scp->status |= scp->splash_save_status;
- splx(s);
- return 1;
- }
-}
-
-static int
-restore_scrn_saver_mode(scr_stat *scp, int changemode)
-{
- int mode;
- int status;
- int s;
+ if (scrn_blanked > 0)
+ return EBUSY; /* XXX */
- /* assert(scp == cur_console) */
- s = spltty();
- mode = scp->mode;
- status = scp->status;
- scp->mode = scp->splash_save_mode;
- scp->status &= ~(UNKNOWN_MODE | SAVER_RUNNING);
- scp->status |= scp->splash_save_status;
- if (!changemode) {
- splx(s);
- return 0;
- }
- if (set_mode(scp) == 0) {
- load_palette(scp->adp, palette);
- splx(s);
- return 0;
- } else {
- scp->mode = mode;
- scp->status = status;
- splx(s);
- return 1;
- }
+ current_saver = default_saver;
+ return 0;
}
static void
@@ -2418,7 +2869,7 @@ stop_scrn_saver(void (*saver)(int))
(*saver)(FALSE);
run_scrn_saver = FALSE;
/* the screen saver may have chosen not to stop after all... */
- if (scrn_blanked)
+ if (scrn_blanked > 0)
return;
mark_all(cur_console);
@@ -2432,8 +2883,8 @@ wait_scrn_saver_stop(void)
{
int error = 0;
- while (scrn_blanked) {
- run_scrn_saver = FALSE;
+ run_scrn_saver = FALSE;
+ while (scrn_blanked > 0) {
error = tsleep((caddr_t)&scrn_blanked, PZERO | PCATCH, "scrsav", 0);
run_scrn_saver = FALSE;
if (error != ERESTART)
@@ -2442,17 +2893,8 @@ wait_scrn_saver_stop(void)
return error;
}
-#endif /* NSPLASH */
-
-void
-sc_touch_scrn_saver(void)
-{
- scsplash_stick(FALSE);
- run_scrn_saver = FALSE;
-}
-
-void
-sc_clear_screen(scr_stat *scp)
+static void
+clear_screen(scr_stat *scp)
{
move_crsr(scp, 0, 0);
scp->cursor_oldpos = scp->cursor_pos;
@@ -2473,9 +2915,10 @@ static int
switch_scr(scr_stat *scp, u_int next_scr)
{
/* delay switch if actively updating screen */
- if (scrn_blanked || write_in_progress || blink_in_progress) {
+ if (scrn_blanked > 0 || write_in_progress || blink_in_progress) {
+ scsplash_stick(FALSE);
+ run_scrn_saver = FALSE;
delayed_next_scr = next_scr+1;
- sc_touch_scrn_saver();
return 0;
}
@@ -2483,7 +2926,8 @@ switch_scr(scr_stat *scp, u_int next_scr)
switch_in_progress = FALSE;
if (next_scr >= MAXCONS || switch_in_progress ||
- (cur_console->smode.mode == VT_AUTO && ISGRAPHSC(cur_console))) {
+ (cur_console->smode.mode == VT_AUTO
+ && cur_console->status & UNKNOWN_MODE)) {
do_bell(scp, BELL_PITCH, BELL_DURATION);
return EINVAL;
}
@@ -2533,35 +2977,33 @@ switch_scr(scr_stat *scp, u_int next_scr)
static void
exchange_scr(void)
{
- /* save the current state of video and keyboard */
move_crsr(old_scp, old_scp->xpos, old_scp->ypos);
- if (old_scp->kbd_mode == K_XLATE)
- save_kbd_state(old_scp);
-
- /* set up the video for the new screen */
cur_console = new_scp;
#ifdef PC98
- if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp) || ISUNKNOWNSC(new_scp))
+ if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE) || (new_scp->status & UNKNOWN_MODE)){
#else
- if (old_scp->mode != new_scp->mode || ISUNKNOWNSC(old_scp))
+ if (old_scp->mode != new_scp->mode || (old_scp->status & UNKNOWN_MODE)){
+ if (crtc_type == KD_VGA)
#endif
- set_mode(new_scp);
+ set_mode(new_scp);
+ }
move_crsr(new_scp, new_scp->xpos, new_scp->ypos);
#ifndef PC98
- if (ISTEXTSC(new_scp) && (sc_flags & CHAR_CURSOR))
+ if (!(new_scp->status & UNKNOWN_MODE) && (flags & CHAR_CURSOR))
set_destructive_cursor(new_scp);
- if (ISGRAPHSC(old_scp))
- load_palette(new_scp->adp, palette);
+ if ((old_scp->status & UNKNOWN_MODE) && crtc_type == KD_VGA)
+ load_palette(palette);
#endif
- set_border(new_scp, new_scp->border);
-
- /* set up the keyboard for the new screen */
- if (old_scp->kbd_mode != new_scp->kbd_mode)
- kbd_ioctl(kbd, KDSKBMODE, (caddr_t)&new_scp->kbd_mode);
- update_kbd_state(new_scp->status, LOCK_MASK);
-
+ if (old_scp->status & KBD_RAW_MODE || new_scp->status & KBD_RAW_MODE ||
+ old_scp->status & KBD_CODE_MODE || new_scp->status & KBD_CODE_MODE)
+ shfts = ctls = alts = agrs = metas = accents = 0;
+ set_border(new_scp->border);
+ update_leds(new_scp->status);
delayed_next_scr = FALSE;
mark_all(new_scp);
+ if (new_scp->mode == 0x102) {
+ bzero(Crtat, 800*600/8);
+ }
}
static void
@@ -2578,36 +3020,36 @@ scan_esc(scr_stat *scp, u_char c)
if (scp->term.esc == 1) { /* seen ESC */
#ifdef KANJI
switch (scp->kanji_type) {
- case KTYPE_KANIN: /* Kanji Invoke sequence */
+ case 0x80:
switch (c) {
case 'B':
case '@':
- scp->kanji_type = KTYPE_7JIS;
+ scp->kanji_type = 0x20;
scp->term.esc = 0;
scp->kanji_1st_char = 0;
return;
default:
- scp->kanji_type = KTYPE_ASCII;
+ scp->kanji_type = 0;
scp->term.esc = 0;
break;
}
break;
- case KTYPE_ASCIN: /* Ascii Invoke sequence */
+ case 0x40:
switch (c) {
case 'J':
case 'B':
case 'H':
- scp->kanji_type = KTYPE_ASCII;
+ scp->kanji_type = 0;
scp->term.esc = 0;
scp->kanji_1st_char = 0;
return;
case 'I':
- scp->kanji_type = KTYPE_JKANA;
+ scp->kanji_type = 0x10;
scp->term.esc = 0;
scp->kanji_1st_char = 0;
return;
default:
- scp->kanji_type = KTYPE_ASCII;
+ scp->kanji_type = 0;
scp->term.esc = 0;
break;
}
@@ -2637,8 +3079,8 @@ scan_esc(scr_stat *scp, u_char c)
return;
#ifdef KANJI
- case '$': /* Kanji Invoke sequence */
- scp->kanji_type = KTYPE_KANIN;
+ case '$': /* Kanji IN sequence */
+ scp->kanji_type = 0x80;
return;
#endif
@@ -2670,12 +3112,12 @@ scan_esc(scr_stat *scp, u_char c)
return;
#endif
case 'c': /* Clear screen & home */
- sc_clear_screen(scp);
+ clear_screen(scp);
break;
case '(': /* iso-2022: designate 94 character set to G0 */
#ifdef KANJI
- scp->kanji_type = KTYPE_ASCIN;
+ scp->kanji_type = 0x40;
#else
scp->term.esc = 5;
#endif
@@ -2772,7 +3214,7 @@ scan_esc(scr_stat *scp, u_char c)
#ifdef PC98
mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
#endif
- mark_for_update(scp, scp->xsize * scp->ysize - 1);
+ mark_for_update(scp, scp->xsize * scp->ysize);
remove_cutmarking(scp);
break;
case 1: /* clear from beginning of display to cursor */
@@ -2835,10 +3277,10 @@ scan_esc(scr_stat *scp, u_char c)
mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
#endif
mark_for_update(scp, scp->cursor_pos - scp->scr_buf +
- scp->xsize - 1 - scp->xpos);
+ scp->xsize - scp->xpos);
#ifdef PC98
mark_for_update(scp, scp->cursor_atr - scp->atr_buf +
- scp->xsize - 1 - scp->xpos);
+ scp->xsize - scp->xpos);
#endif
break;
case 1: /* clear from beginning of line to cursor */
@@ -2874,7 +3316,7 @@ scan_esc(scr_stat *scp, u_char c)
scp->xsize);
#endif
mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, (scp->ypos + 1) * scp->xsize - 1);
+ mark_for_update(scp, (scp->ypos + 1) * scp->xsize);
break;
}
break;
@@ -2900,7 +3342,7 @@ scan_esc(scr_stat *scp, u_char c)
n * scp->xsize);
#endif
mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->xsize * scp->ysize - 1);
+ mark_for_update(scp, scp->xsize * scp->ysize);
break;
case 'M': /* Delete n lines */
@@ -2926,7 +3368,7 @@ scan_esc(scr_stat *scp, u_char c)
n * scp->xsize);
#endif
mark_for_update(scp, scp->ypos * scp->xsize);
- mark_for_update(scp, scp->xsize * scp->ysize - 1);
+ mark_for_update(scp, scp->xsize * scp->ysize);
break;
case 'P': /* Delete n chars */
@@ -2952,9 +3394,9 @@ scan_esc(scr_stat *scp, u_char c)
#ifdef PC98
mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
+ mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count - 1);
+ mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count);
#endif
break;
@@ -2979,9 +3421,9 @@ scan_esc(scr_stat *scp, u_char c)
#ifdef PC98
mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count - 1);
+ mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n + count);
#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count - 1);
+ mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n + count);
#endif
break;
@@ -3051,9 +3493,9 @@ scan_esc(scr_stat *scp, u_char c)
#ifdef PC98
mark_for_update(scp, scp->cursor_atr - scp->atr_buf);
#endif
- mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n - 1);
+ mark_for_update(scp, scp->cursor_pos - scp->scr_buf + n);
#ifdef PC98
- mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n - 1);
+ mark_for_update(scp, scp->cursor_atr - scp->atr_buf + n);
#endif
break;
@@ -3125,7 +3567,7 @@ scan_esc(scr_stat *scp, u_char c)
scp->term.cur_color =
(scp->term.cur_color&0xF000) | (ansi_col[(n-30)&7]<<8);
scp->term.cur_attr = mask2attr(&scp->term);
- break;
+ break;
case 40: case 41: /* set bg color */
case 42: case 43: case 44:
case 45: case 46: case 47:
@@ -3232,7 +3674,7 @@ scan_esc(scr_stat *scp, u_char c)
if (scp->term.num_param == 1) {
scp->border=scp->term.param[0] & 0xff;
if (scp == cur_console)
- set_border(cur_console, scp->border);
+ set_border(scp->border);
}
break;
@@ -3246,21 +3688,14 @@ scan_esc(scr_stat *scp, u_char c)
case 'C': /* set cursor type & shape */
if (scp->term.num_param == 1) {
if (scp->term.param[0] & 0x01)
- sc_flags |= BLINK_CURSOR;
- else
- sc_flags &= ~BLINK_CURSOR;
-#ifdef PC98
- if (scp->term.param[0] & 0x02)
- sc_flags |= CHAR_CURSOR;
+ flags |= BLINK_CURSOR;
else
- sc_flags &= ~CHAR_CURSOR;
-#else /* PC98 */
- if ((scp->term.param[0] & 0x02)
- && ISFONTAVAIL(scp->adp->va_flags))
- sc_flags |= CHAR_CURSOR;
+ flags &= ~BLINK_CURSOR;
+ if ((scp->term.param[0] & 0x02) &&
+ crtc_type == KD_VGA && !VESA_MODE(bios_video_mode))
+ flags |= CHAR_CURSOR;
else
- sc_flags &= ~CHAR_CURSOR;
-#endif /* PC98 */
+ flags &= ~CHAR_CURSOR;
}
else if (scp->term.num_param == 2) {
scp->cursor_start = scp->term.param[0] & 0x1F;
@@ -3270,13 +3705,11 @@ scan_esc(scr_stat *scp, u_char c)
* The cursor shape is global property; all virtual consoles
* are affected. Update the cursor in the current console...
*/
- if (!ISGRAPHSC(cur_console)) {
- i = spltty();
+ if (!(cur_console->status & UNKNOWN_MODE)) {
remove_cursor_image(cur_console);
- if (sc_flags & CHAR_CURSOR)
+ if (crtc_type == KD_VGA && (flags & CHAR_CURSOR))
set_destructive_cursor(cur_console);
draw_cursor_image(cur_console);
- splx(i);
}
break;
@@ -3339,114 +3772,103 @@ scan_esc(scr_stat *scp, u_char c)
#ifdef KANJI
static u_char iskanji1(u_char mode, u_char c)
{
- if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) {
+ if ((mode == 0x20) && (c >= 0x21) && (c <= 0x7e)) {
/* JIS */
- default_kanji = UJIS;
- return KTYPE_7JIS;
+ return 0x20;
}
- if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) {
+ if ((mode == 0x10) && (c >= 0x21) && (c <= 0x5f)) {
/* JIS HANKAKU */
- default_kanji = UJIS;
- return KTYPE_JKANA;
- }
-
-#if 1
- if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) {
- /* UJIS */
- return KTYPE_UJIS;
+ return 0x10;
}
-#endif
if ((c >= 0x81) && (c <= 0x9f) && (c != 0x8e)) {
/* SJIS */
default_kanji = SJIS;
- return KTYPE_SJIS;
+ return 2;
}
if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == SJIS)) {
- /* SJIS HANKAKU */
- return KTYPE_KANA;
+ /* Sjis HANKAKU */
+ return 1;
}
-#if 0
if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) {
/* UJIS */
- return KTYPE_UJIS;
+ return 4;
}
-#endif
if ((c >= 0xf0) && (c <= 0xfe)) {
/* UJIS */
default_kanji = UJIS;
- return KTYPE_UJIS;
+ return 4;
}
if ((c >= 0xe0) && (c <= 0xef)) {
/* SJIS or UJIS */
- return KTYPE_SUJIS;
+ return 6;
}
if (c == 0x8e) {
/* SJIS or UJIS HANKAKU */
- return KTYPE_SUKANA;
+ return 3;
}
- return KTYPE_ASCII;
+ return 0;
}
static u_char iskanji2(u_char mode, u_char c)
{
switch (mode) {
- case KTYPE_7JIS:
+ case 0x20:
if ((c >= 0x21) && (c <= 0x7e)) {
/* JIS */
- return KTYPE_7JIS;
+ return 0x20;
}
break;
- case KTYPE_SJIS:
+ case 2:
if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) {
/* SJIS */
- return KTYPE_SJIS;
+ return 2;
}
break;
- case KTYPE_UJIS:
+ case 4:
if ((c >= 0xa1) && (c <= 0xfe)) {
/* UJIS */
- return KTYPE_UJIS;
+ return 4;
}
break;
- case KTYPE_SUKANA:
+ case 3:
if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) {
/* UJIS HANKAKU */
- return KTYPE_KANA;
+ return 1;
}
if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) {
/* SJIS */
default_kanji = SJIS;
- return KTYPE_SJIS;
+ return 2;
}
break;
- case KTYPE_SUJIS:
+ case 6:
if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) {
/* SJIS */
default_kanji = SJIS;
- return KTYPE_SJIS;
+ return 2;
}
if ((c == 0xfd) || (c == 0xfe)) {
/* UJIS */
default_kanji = UJIS;
- return KTYPE_UJIS;
+ return 4;
}
if ((c >= 0xa1) && (c <= 0xfc)) {
if (default_kanji == SJIS)
- return KTYPE_SJIS;
+ return 2;
if (default_kanji == UJIS)
- return KTYPE_UJIS;
+ return 4;
}
break;
}
- return KTYPE_ASCII;
+ return 0;
}
/*
@@ -3467,7 +3889,7 @@ static u_short kanji_convert(u_char mode, u_char h, u_char l)
low = (u_short) l;
switch (mode) {
- case KTYPE_SJIS: /* SHIFT JIS */
+ case 2: /* SHIFT JIS */
if (low >= 0xe0) {
low -= 0x40;
}
@@ -3475,7 +3897,7 @@ static u_short kanji_convert(u_char mode, u_char h, u_char l)
if (high > 0x7f) {
high--;
}
- if (high > 0x9d) {
+ if (high >0x9d) {
low++;
high -= 0x9e - 0x21;
} else {
@@ -3485,8 +3907,8 @@ static u_short kanji_convert(u_char mode, u_char h, u_char l)
low &= 0x7F;
tmp = ((high << 8) | low) - 0x20;
break;
- case KTYPE_7JIS: /* JIS */
- case KTYPE_UJIS: /* UJIS */
+ case 0x20: /* JIS */
+ case 4: /* HANKAKU? */
high &= 0x7F;
low &= 0x7F;
tmp = ((high << 8) | low) - 0x20;
@@ -3498,7 +3920,6 @@ static u_short kanji_convert(u_char mode, u_char h, u_char l)
/* keisen */
c = ((tmp & 0xff) << 8) | (tmp >> 8);
- /* 0x2821 .. 0x2840 */
if (0x0821 <= c && c <= 0x0840)
tmp = keiConv[c - 0x0821];
@@ -3525,9 +3946,7 @@ outloop:
len--;
}
else if (PRINTABLE(*ptr)) { /* Print only printables */
-#ifndef PC98
int cnt = len <= (scp->xsize-scp->xpos) ? len : (scp->xsize-scp->xpos);
-#endif
u_short cur_attr = scp->term.cur_attr;
u_short *cursor_pos = scp->cursor_pos;
#ifdef PC98
@@ -3536,7 +3955,7 @@ outloop:
#ifdef KANJI
if (scp->kanji_1st_char == 0) {
scp->kanji_type = iskanji1(scp->kanji_type, c);
- if (!IS_KTYPE_ASCII_or_HANKAKU(scp->kanji_type)) {
+ if (scp->kanji_type & 0xee) {
/* not Ascii & not HANKAKU */
scp->kanji_1st_char = c;
ptr++; len--;
@@ -3549,8 +3968,7 @@ outloop:
/* print kanji on TEXT VRAM */
kanji_code = kanji_convert(scp->kanji_type, c, scp->kanji_1st_char);
for (i=0; i<2; i++){
- /* *cursor_pos = (kanji_code | (i*0x80)); */
- *cursor_pos = kanji_code | ((i==0) ? 0x00 : 0x80);
+ *cursor_pos = (kanji_code | (i*0x80));
*cursor_atr = (at2pc98(cur_attr));
cursor_pos++;
cursor_atr++;
@@ -3559,7 +3977,7 @@ outloop:
scp->ypos++;
}
}
- KTYPE_MASK_CTRL(scp->kanji_type);
+ scp->kanji_type &= 0xF0;
scp->kanji_1st_char = 0;
ptr++; len--;
goto kanji_end;
@@ -3567,9 +3985,8 @@ outloop:
scp->kanji_1st_char = 0;
}
}
- if (IS_KTYPE_KANA(scp->kanji_type))
- c |= 0x80;
- KTYPE_MASK_CTRL(scp->kanji_type);
+ if ((scp->kanji_type & 0x11)) c |= 0x80;
+ scp->kanji_type &= 0xf0;
#endif /* KANJI */
*cursor_pos++ = (scr_map[c]);
*cursor_atr++ = at2pc98(cur_attr);
@@ -3675,7 +4092,7 @@ kanji_end:
break;
case 0x0c: /* form feed, clears screen */
- sc_clear_screen(scp);
+ clear_screen(scp);
break;
case 0x0d: /* return, return to pos 0 */
@@ -3694,20 +4111,6 @@ kanji_end:
scp->xpos = 0;
break;
-#ifdef PC98
- case 0x0e: /* ^N */
- scp->kanji_type = KTYPE_JKANA;
- scp->term.esc = 0;
- scp->kanji_1st_char = 0;
- break;
-
- case 0x0f: /* ^O */
- scp->kanji_type = KTYPE_ASCII;
- scp->term.esc = 0;
- scp->kanji_1st_char = 0;
- break;
-#endif
-
case 0x1b: /* start escape sequence */
scp->term.esc = 1;
scp->term.num_param = 0;
@@ -3718,7 +4121,7 @@ kanji_end:
/* do we have to scroll ?? */
if (scp->cursor_pos >= scp->scr_buf + scp->ysize * scp->xsize) {
remove_cutmarking(scp);
- if (scp->history != NULL) {
+ if (scp->history) {
bcopy(scp->scr_buf, scp->history_head,
scp->xsize * sizeof(u_short));
scp->history_head += scp->xsize;
@@ -3734,8 +4137,7 @@ kanji_end:
#endif
scp->history_head = scp->history;
#ifdef PC98
- scp->his_atr_head = scp->his_atr;
- }
+ scp->his_atr_head = scp->his_atr; }
#endif
}
bcopy(scp->scr_buf + scp->xsize, scp->scr_buf,
@@ -3772,30 +4174,66 @@ kanji_end:
static void
scinit(void)
{
- video_adapter_t *adp;
- int col;
- int row;
+ u_int hw_cursor;
u_int i;
if (init_done != COLD)
return;
init_done = WARM;
- get_bios_values();
-
#ifdef PC98
- if (pc98_machine_type & M_8M)
- BELL_PITCH = 1339;
- else
- BELL_PITCH = 1678;
-#endif
+ if (pc98_machine_type & M_8M) {
+ BELL_PITCH = 1339;
+ } else {
+ BELL_PITCH = 1678;
+ }
+ outb(0x62, 0xd);
+ outb(0xA2, 0xd);
+ /* Extract cursor location */
+ while((inb(TEXT_GDC + 0) & 0x04) == 0) {} /* GDC wait */
+ outb(TEXT_GDC + 2, 0xe0); /* CSRR */
+ while((inb(TEXT_GDC + 0) & 0x1) == 0) {} /* GDC wait */
+ hw_cursor = inb(TEXT_GDC + 2); /* EADl */
+ hw_cursor |= (inb(TEXT_GDC + 2) << 8); /* EADh */
+ inb(TEXT_GDC + 2); /* dummy */
+ inb(TEXT_GDC + 2); /* dummy */
+ inb(TEXT_GDC + 2); /* dummy */
- /* extract the hardware cursor location and hide the cursor for now */
- adp = vid_get_adapter(adapter);
- (*vidsw[adapter]->read_hw_cursor)(adp, &col, &row);
-#ifndef PC98
- (*vidsw[adapter]->set_hw_cursor)(adp, -1, -1);
-#endif
+ if (hw_cursor >= ROW*COL) {
+ hw_cursor = 0;
+ }
+ crtc_vga = TRUE;
+#else /* IBM-PC */
+ /*
+ * Ensure a zero start address. This is mainly to recover after
+ * switching from pcvt using userconfig(). The registers are w/o
+ * for old hardware so it's too hard to relocate the active screen
+ * memory.
+ */
+ outb(crtc_addr, 12);
+ outb(crtc_addr + 1, 0);
+ outb(crtc_addr, 13);
+ outb(crtc_addr + 1, 0);
+
+ /* extract cursor location */
+ outb(crtc_addr, 14);
+ hw_cursor = inb(crtc_addr + 1) << 8;
+ outb(crtc_addr, 15);
+ hw_cursor |= inb(crtc_addr + 1);
+
+ /*
+ * Validate cursor location. It may be off the screen. Then we must
+ * not use it for the initial buffer offset.
+ */
+ if (hw_cursor >= ROW * COL)
+ hw_cursor = (ROW - 1) * COL;
+
+ /* move hardware cursor out of the way */
+ outb(crtc_addr, 14);
+ outb(crtc_addr + 1, 0xff);
+ outb(crtc_addr, 15);
+ outb(crtc_addr + 1, 0xff);
+#endif /* PC98 */
/* set up the first console */
current_default = &user_default;
@@ -3803,27 +4241,57 @@ scinit(void)
init_scp(console[0]);
cur_console = console[0];
+#ifndef PC98
+ /* discard the video mode table if we are not familiar with it... */
+ if (video_mode_ptr) {
+ bzero(mode_map, sizeof(mode_map));
+ bcopy(video_mode_ptr + MODE_PARAM_SIZE*console[0]->mode,
+ vgaregs2, sizeof(vgaregs2));
+ switch (comp_vgaregs(vgaregs, video_mode_ptr
+ + MODE_PARAM_SIZE*console[0]->mode)) {
+ case COMP_IDENTICAL:
+ map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1);
+ /*
+ * This is a kludge for Toshiba DynaBook SS433 whose BIOS video
+ * mode table entry has the actual # of rows at the offset 1;
+ * BIOSes from other manufacturers store the # of rows - 1 there.
+ * XXX
+ */
+ rows_offset = vgaregs[1] + 1
+ - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1];
+ break;
+ case COMP_SIMILAR:
+ map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1);
+ mode_map[console[0]->mode] = vgaregs;
+ rows_offset = vgaregs[1] + 1
+ - video_mode_ptr[MODE_PARAM_SIZE*console[0]->mode + 1];
+ vgaregs[1] -= rows_offset - 1;
+ break;
+ case COMP_DIFFERENT:
+ default:
+ video_mode_ptr = NULL;
+ mode_map[console[0]->mode] = vgaregs;
+ rows_offset = 1;
+ break;
+ }
+ }
+#endif
/* copy screen to temporary buffer */
- if (ISTEXTSC(console[0]))
- generic_bcopy((ushort *)(console[0]->adp->va_window), sc_buffer,
- console[0]->xsize * console[0]->ysize * sizeof(u_short));
+ if (!VESA_MODE(console[0]->mode))
+ generic_bcopy(Crtat, sc_buffer,
+ console[0]->xsize * console[0]->ysize * sizeof(u_short));
console[0]->scr_buf = console[0]->mouse_pos = console[0]->mouse_oldpos
= sc_buffer;
- if (col >= console[0]->xsize)
- col = 0;
- if (row >= console[0]->ysize)
- row = console[0]->ysize - 1;
- console[0]->xpos = col;
- console[0]->ypos = row;
- console[0]->cursor_pos = console[0]->cursor_oldpos =
- sc_buffer + row*console[0]->xsize + col;
-#ifndef PC98
- console[0]->cursor_saveunder = *console[0]->cursor_pos;
-#else
+ console[0]->cursor_pos = console[0]->cursor_oldpos = sc_buffer + hw_cursor;
+#ifdef PC98
console[0]->atr_buf = Atrat;
- console[0]->cursor_atr = Atrat + row*console[0]->xsize + col;
+ console[0]->cursor_atr = Atrat + hw_cursor;
+#else
+ console[0]->cursor_saveunder = *console[0]->cursor_pos;
#endif
+ console[0]->xpos = hw_cursor % COL;
+ console[0]->ypos = hw_cursor / COL;
for (i=1; i<MAXCONS; i++)
console[i] = NULL;
kernel_console.esc = 0;
@@ -3838,141 +4306,93 @@ scinit(void)
scr_map[i] = scr_rmap[i] = i;
}
#ifdef PC98
- scr_map[0x5c] = (u_char)0xfc; /* for backslash */
+ scr_map[0x5c] = (u_char)0xfc; /* for backslash */
#endif
- /* Save font and palette */
- if (ISFONTAVAIL(cur_console->adp->va_flags)) {
- if (fonts_loaded & FONT_16) {
- copy_font(cur_console, LOAD, 16, font_16);
- } else {
- copy_font(cur_console, SAVE, 16, font_16);
- fonts_loaded = FONT_16;
- set_destructive_cursor(cur_console);
+#ifndef PC98
+ /* Save font and palette if VGA */
+ if (crtc_type == KD_VGA) {
+ if (!VESA_MODE(bios_video_mode)) {
+ if (fonts_loaded & FONT_16) {
+ copy_font(LOAD, FONT_16, font_16);
+ } else {
+ copy_font(SAVE, FONT_16, font_16);
+ fonts_loaded = FONT_16;
+ }
+ set_destructive_cursor(console[0]);
}
- /*
- * FONT KLUDGE
- * Always use the font page #0. XXX
- */
- (*vidsw[cur_console->ad]->show_font)(cur_console->adp, 0);
+ save_palette();
}
- save_palette(cur_console->adp, palette);
-#if NSPLASH > 0
- /* we are ready to put up the splash image! */
- splash_init(cur_console->adp, scsplash_callback);
+#ifdef SC_SPLASH_SCREEN
+ /*
+ * If not booting verbosely, put up the splash.
+ * Note that the splash screen is not currently supported in
+ * the VESA mode.
+ */
+ if (!(boothowto & RB_VERBOSE) && !VESA_MODE(bios_video_mode))
+ scsplash_init();
+#endif
#endif
}
static void
scshutdown(int howto, void *arg)
{
- sc_touch_scrn_saver();
+ scsplash_stick(FALSE);
+ run_scrn_saver = FALSE;
if (!cold && cur_console->smode.mode == VT_AUTO
&& console[0]->smode.mode == VT_AUTO)
switch_scr(cur_console, 0);
shutdown_in_progress = TRUE;
}
-int
-sc_clean_up(scr_stat *scp)
+static void
+map_mode_table(char *map[], char *table, int max)
{
- int error;
+ int i;
- sc_touch_scrn_saver();
-#if NSPLASH > 0
- if ((error = wait_scrn_saver_stop()))
- return error;
-#endif /* NSPLASH */
- scp->status &= ~MOUSE_VISIBLE;
- remove_cutmarking(scp);
- return 0;
+ for(i = 0; i < max; ++i)
+ map[i] = table + i*MODE_PARAM_SIZE;
+ for(; i < MODE_MAP_SIZE; ++i)
+ map[i] = NULL;
}
-void
-sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear)
+static int
+map_mode_num(int mode)
{
- if (scp->scr_buf)
- free(scp->scr_buf, M_DEVBUF);
- scp->scr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
-#ifdef PC98
- if (scp->atr_buf)
- free(scp->atr_buf, M_DEVBUF);
- scp->atr_buf = (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
-#endif
-
- if (clear) {
- /* clear the screen and move the text cursor to the top-left position */
- sc_clear_screen(scp);
- } else {
- /* retain the current cursor position, but adjust pointers */
- move_crsr(scp, scp->xpos, scp->ypos);
- scp->cursor_oldpos = scp->cursor_pos;
- }
-
- /* move the mouse cursor at the center of the screen */
- sc_move_mouse(scp, scp->xpixel / 2, scp->ypixel / 2);
-}
+ static struct {
+ int from;
+ int to;
+ } mode_map[] = {
+ { M_ENH_B80x43, M_ENH_B80x25 },
+ { M_ENH_C80x43, M_ENH_C80x25 },
+ { M_VGA_M80x30, M_VGA_M80x25 },
+ { M_VGA_C80x30, M_VGA_C80x25 },
+ { M_VGA_M80x50, M_VGA_M80x25 },
+ { M_VGA_C80x50, M_VGA_C80x25 },
+ { M_VGA_M80x60, M_VGA_M80x25 },
+ { M_VGA_C80x60, M_VGA_C80x25 },
+ { M_VGA_MODEX, M_VGA_CG320 },
+ };
+ int i;
-void
-sc_alloc_cut_buffer(scr_stat *scp, int wait)
-{
- if ((cut_buffer == NULL)
- || (cut_buffer_size < scp->xsize * scp->ysize + 1)) {
- if (cut_buffer != NULL)
- free(cut_buffer, M_DEVBUF);
- cut_buffer_size = scp->xsize * scp->ysize + 1;
- cut_buffer = (u_char *)malloc(cut_buffer_size,
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
- if (cut_buffer != NULL)
- cut_buffer[0] = '\0';
+ for (i = 0; i < sizeof(mode_map)/sizeof(mode_map[0]); ++i) {
+ if (mode_map[i].from == mode)
+ return mode_map[i].to;
}
+ return mode;
}
-void
-sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait)
+static char
+*get_mode_param(scr_stat *scp, int mode)
{
- u_short *usp;
-#ifdef PC98
- u_short *atr_usp;
-#endif
-
- if (lines < scp->ysize)
- lines = scp->ysize;
-
- usp = scp->history;
- scp->history = NULL;
- if (usp != NULL) {
- free(usp, M_DEVBUF);
- if (extra > 0)
- extra_history_size += extra;
- }
-#ifdef PC98
- atr_usp = scp->his_atr;
- scp->his_atr = NULL;
- if (atr_usp != NULL)
- free(atr_usp, M_DEVBUF);
-#endif
-
- scp->history_size = lines * scp->xsize;
- if (lines > imax(sc_history_size, scp->ysize))
- extra_history_size -= lines - imax(sc_history_size, scp->ysize);
- usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
- if (usp != NULL)
- bzero(usp, scp->history_size * sizeof(u_short));
- scp->history_head = scp->history_pos = usp;
- scp->history = usp;
-#ifdef PC98
- atr_usp = (u_short *)malloc(scp->history_size * sizeof(u_short),
- M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
- if (atr_usp != NULL)
- bzero(atr_usp, scp->history_size * sizeof(u_short));
- scp->his_atr_head = scp->his_atr_pos = atr_usp;
- scp->his_atr = atr_usp;
-#endif
+ if (mode >= MODE_MAP_SIZE)
+ mode = map_mode_num(mode);
+ if (mode < MODE_MAP_SIZE)
+ return mode_map[mode];
+ else
+ return NULL;
}
static scr_stat
@@ -3982,21 +4402,34 @@ static scr_stat
scp = (scr_stat *)malloc(sizeof(scr_stat), M_DEVBUF, M_WAITOK);
init_scp(scp);
- sc_alloc_scr_buffer(scp, TRUE, TRUE);
+ scp->scr_buf = scp->cursor_pos = scp->cursor_oldpos =
+ (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
+ M_DEVBUF, M_WAITOK);
+ scp->mouse_pos = scp->mouse_oldpos =
+ scp->scr_buf + ((scp->mouse_ypos/scp->font_size)*scp->xsize +
+ scp->mouse_xpos/8);
+ scp->history_head = scp->history_pos =
+ (u_short *)malloc(scp->history_size*sizeof(u_short),
+ M_DEVBUF, M_WAITOK);
+ bzero(scp->history_head, scp->history_size*sizeof(u_short));
+ scp->history = scp->history_head;
#ifdef PC98
- sc_alloc_cut_buffer(scp, TRUE);
-#else /* PC98 */
- if (ISMOUSEAVAIL(scp->adp->va_flags))
- sc_alloc_cut_buffer(scp, TRUE);
-#endif /* PC98 */
- sc_alloc_history_buffer(scp, sc_history_size, 0, TRUE);
+ scp->atr_buf = scp->cursor_atr = scp->atr_buf =
+ (u_short *)malloc(scp->xsize*scp->ysize*sizeof(u_short),
+ M_DEVBUF, M_WAITOK);
+ scp->his_atr_head = scp->his_atr_pos =
+ (u_short *)malloc(scp->history_size*sizeof(u_short),
+ M_DEVBUF, M_WAITOK);
+ bzero(scp->his_atr_head, scp->history_size*sizeof(u_short));
+ scp->his_atr = scp->his_atr_head;
+#endif
/* SOS
#ifndef PC98
- if (scp->adp->va_flags & V_ADP_MODECHANGE)
+ if (crtc_type == KD_VGA && video_mode_ptr)
#endif
set_mode(scp);
*/
- sc_clear_screen(scp);
+ clear_screen(scp);
#ifndef PC98
scp->cursor_saveunder = *scp->cursor_pos;
#endif
@@ -4006,30 +4439,47 @@ static scr_stat
static void
init_scp(scr_stat *scp)
{
- video_info_t info;
-
- scp->ad = adapter;
- scp->adp = vid_get_adapter(scp->ad);
- (*vidsw[scp->ad]->get_info)(scp->adp, initial_video_mode, &info);
-
- scp->status = 0;
- scp->mode = initial_video_mode;
- scp->scr_buf = NULL;
- if (info.vi_flags & V_INFO_GRAPHICS) {
- scp->status |= GRAPHICS_MODE;
- scp->xpixel = info.vi_width;
- scp->ypixel = info.vi_height;
- scp->xsize = info.vi_width/8;
- scp->ysize = info.vi_height/info.vi_cheight;
- scp->font_size = FONT_NONE;
- } else {
- scp->xsize = info.vi_width;
- scp->ysize = info.vi_height;
- scp->xpixel = scp->xsize*8;
- scp->ypixel = scp->ysize*info.vi_cheight;
- scp->font_size = info.vi_cheight;
+#ifdef PC98
+ scp->mode = M_PC98_80x25;
+ scp->font_size = 16;
+#else
+ switch(crtc_type) {
+ case KD_VGA:
+ if (VESA_MODE(bios_video_mode))
+ scp->mode = bios_video_mode;
+ else if (crtc_addr == MONO_BASE)
+ scp->mode = M_VGA_M80x25;
+ else
+ scp->mode = M_VGA_C80x25;
+ else
+ scp->font_size = 16;
+ break;
+ case KD_CGA:
+ if (crtc_addr == MONO_BASE)
+ scp->mode = M_B80x25;
+ else
+ scp->mode = M_C80x25;
+ scp->font_size = 8;
+ break;
+ case KD_EGA:
+ scp->mode = M_B80x25;
+ else
+ scp->mode = M_C80x25;
+ scp->font_size = 14;
+ break;
+ case KD_MONO:
+ case KD_HERCULES:
+ default:
+ scp->mode = M_EGAMONO80x25;
+ scp->font_size = 14;
+ break;
}
- scp->xoff = scp->yoff = 0;
+ scp->initial_mode = scp->mode;
+#endif
+ scp->xsize = COL;
+ scp->ysize = ROW;
+ scp->xpixel = scp->xsize * 8;
+ scp->ypixel = scp->ysize * scp->font_size;
scp->xpos = scp->ypos = 0;
scp->saved_xpos = scp->saved_ypos = -1;
scp->start = scp->xsize * scp->ysize;
@@ -4041,21 +4491,28 @@ init_scp(scr_stat *scp)
current_default->std_color;
scp->term.rev_color = current_default->rev_color;
scp->border = BG_BLACK;
- scp->cursor_start = bios_value.cursor_start;
- scp->cursor_end = bios_value.cursor_end;
+#ifdef PC98
+ scp->cursor_start = 0;
+ scp->cursor_end = 0;
+#else
+ scp->cursor_start = *(char *)pa_to_va(0x461);
+ scp->cursor_end = *(char *)pa_to_va(0x460);
+#endif
scp->mouse_xpos = scp->xsize*8/2;
scp->mouse_ypos = scp->ysize*scp->font_size/2;
scp->mouse_cut_start = scp->mouse_cut_end = NULL;
scp->mouse_signal = 0;
scp->mouse_pid = 0;
scp->mouse_proc = NULL;
- scp->kbd_mode = K_XLATE;
scp->bell_pitch = BELL_PITCH;
scp->bell_duration = BELL_DURATION;
-#ifndef PC98
- scp->status |= (bios_value.shift_state & 0x20) ? NLKED : 0;
-#endif
+#ifdef PC98
+ scp->status = 0;
scp->status |= CURSOR_ENABLED;
+#else
+ scp->status = (*(char *)pa_to_va(0x417) & 0x20) ? NLKED : 0;
+ scp->status |= CURSOR_ENABLED;
+#endif
scp->pid = 0;
scp->proc = NULL;
scp->smode.mode = VT_AUTO;
@@ -4063,25 +4520,25 @@ init_scp(scr_stat *scp)
#ifdef PC98
scp->his_atr_head = scp->his_atr_pos = scp->his_atr = NULL;
#endif
- scp->history_size = imax(sc_history_size, scp->ysize) * scp->xsize;
+ scp->history_size = imax(SC_HISTORY_SIZE, scp->ysize) * scp->xsize;
#ifdef KANJI
scp->kanji_1st_char = 0;
- scp->kanji_type = KTYPE_ASCII;
+ scp->kanji_type = 0;
#endif
}
-static void
-get_bios_values(void)
+static u_char
+*get_fstr(u_int c, u_int *len)
{
-#ifdef PC98
- bios_value.cursor_start = 0;
- bios_value.cursor_end = 0;
- bios_value.shift_state = 0;
-#else /* !PC98 */
- bios_value.cursor_start = *(u_int8_t *)pa_to_va(0x461);
- bios_value.cursor_end = *(u_int8_t *)pa_to_va(0x460);
- bios_value.shift_state = *(u_int8_t *)pa_to_va(0x417);
-#endif
+ u_int i;
+
+ if (!(c & FKEY))
+ return(NULL);
+ i = (c & 0xFF) - F_FN;
+ if (i > n_fkey_tab)
+ return(NULL);
+ *len = fkey_tab[i].len;
+ return(fkey_tab[i].str);
}
static void
@@ -4144,46 +4601,151 @@ history_down_line(scr_stat *scp)
* return NOKEY if there is nothing there.
*/
static u_int
-scgetc(keyboard_t *kbd, u_int flags)
+scgetc(u_int flags)
{
- u_int c;
- int this_scr;
- int f;
- int i;
-
- if (kbd == NULL)
- return NOKEY;
+ struct key_t *key;
+ u_char scancode, keycode;
+ u_int state, action;
+ int c;
+ static u_char esc_flag = 0, compose = 0;
+ static u_int chr = 0;
next_code:
- /* I don't like this, but... XXX */
- if (flags & SCGETC_CN)
- sccnupdate(cur_console);
/* first see if there is something in the keyboard port */
- for (;;) {
- c = kbd_read_char(kbd, !(flags & SCGETC_NONBLOCK));
- if (c == ERRKEY) {
- if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
- } else if (c == NOKEY)
- return c;
- else
- break;
+ if (flags & SCGETC_NONBLOCK) {
+ c = read_kbd_data_no_wait(sc_kbdc);
+ if (c == -1)
+ return(NOKEY);
+ } else {
+ do {
+ c = read_kbd_data(sc_kbdc);
+ } while(c == -1);
}
+ scancode = (u_char)c;
/* make screensaver happy */
- if (!(c & RELKEY))
- sc_touch_scrn_saver();
+ if (!(scancode & 0x80)) {
+ scsplash_stick(FALSE);
+ run_scrn_saver = FALSE;
+ }
- if (!(flags & SCGETC_CN))
+ if (!(flags & SCGETC_CN)) {
/* do the /dev/random device a favour */
- add_keyboard_randomness(c);
+ add_keyboard_randomness(scancode);
+
+ if (cur_console->status & KBD_RAW_MODE)
+ return scancode;
+ }
+
+ keycode = scancode & 0x7F;
+ switch (esc_flag) {
+ case 0x00: /* normal scancode */
+ switch(scancode) {
+ case 0xB8: /* left alt (compose key) */
+ if (compose) {
+ compose = 0;
+ if (chr > 255) {
+ do_bell(cur_console,
+ BELL_PITCH, BELL_DURATION);
+ chr = 0;
+ }
+ }
+ break;
+ case 0x38:
+ if (!compose) {
+ compose = 1;
+ chr = 0;
+ }
+ break;
+ case 0xE0:
+ case 0xE1:
+ esc_flag = scancode;
+ goto next_code;
+ }
+ break;
+ case 0xE0: /* 0xE0 prefix */
+ esc_flag = 0;
+ switch (keycode) {
+ case 0x1C: /* right enter key */
+ keycode = 0x59;
+ break;
+ case 0x1D: /* right ctrl key */
+ keycode = 0x5A;
+ break;
+ case 0x35: /* keypad divide key */
+ keycode = 0x5B;
+ break;
+ case 0x37: /* print scrn key */
+ keycode = 0x5C;
+ break;
+ case 0x38: /* right alt key (alt gr) */
+ keycode = 0x5D;
+ break;
+ case 0x47: /* grey home key */
+ keycode = 0x5E;
+ break;
+ case 0x48: /* grey up arrow key */
+ keycode = 0x5F;
+ break;
+ case 0x49: /* grey page up key */
+ keycode = 0x60;
+ break;
+ case 0x4B: /* grey left arrow key */
+ keycode = 0x61;
+ break;
+ case 0x4D: /* grey right arrow key */
+ keycode = 0x62;
+ break;
+ case 0x4F: /* grey end key */
+ keycode = 0x63;
+ break;
+ case 0x50: /* grey down arrow key */
+ keycode = 0x64;
+ break;
+ case 0x51: /* grey page down key */
+ keycode = 0x65;
+ break;
+ case 0x52: /* grey insert key */
+ keycode = 0x66;
+ break;
+ case 0x53: /* grey delete key */
+ keycode = 0x67;
+ break;
- if (cur_console->kbd_mode != K_XLATE)
- return KEYCHAR(c);
+ /* the following 3 are only used on the MS "Natural" keyboard */
+ case 0x5b: /* left Window key */
+ keycode = 0x69;
+ break;
+ case 0x5c: /* right Window key */
+ keycode = 0x6a;
+ break;
+ case 0x5d: /* menu key */
+ keycode = 0x6b;
+ break;
+ default: /* ignore everything else */
+ goto next_code;
+ }
+ break;
+ case 0xE1: /* 0xE1 prefix */
+ esc_flag = 0;
+ if (keycode == 0x1D)
+ esc_flag = 0x1D;
+ goto next_code;
+ /* NOT REACHED */
+ case 0x1D: /* pause / break */
+ esc_flag = 0;
+ if (keycode != 0x45)
+ goto next_code;
+ keycode = 0x68;
+ break;
+ }
+
+ if (!(flags & SCGETC_CN) && (cur_console->status & KBD_CODE_MODE))
+ return (keycode | (scancode & 0x80));
/* if scroll-lock pressed allow history browsing */
- if (!ISGRAPHSC(cur_console) && cur_console->history
- && cur_console->status & SLKED) {
+ if (cur_console->history && cur_console->status & SLKED) {
+ int i;
cur_console->status &= ~CURSOR_ENABLED;
if (!(cur_console->status & BUFFER_SAVED)) {
@@ -4209,11 +4771,10 @@ next_code:
cur_console->history + cur_console->history_size)
#ifdef PC98
{
+#endif
cur_console->history_head=cur_console->history;
- cur_console->his_atr_head=cur_console->his_atr;
- }
-#else
- cur_console->history_head=cur_console->history;
+#ifdef PC98
+ cur_console->his_atr_head=cur_console->his_atr; }
#endif
}
cur_console->history_pos = cur_console->history_head;
@@ -4222,10 +4783,12 @@ next_code:
#endif
history_to_screen(cur_console);
}
- switch (c) {
- /* FIXME: key codes */
- case SPCLKEY | FKEY | F(49): /* home key */
- remove_cutmarking(cur_console);
+ switch (scancode) {
+#ifdef PC98
+ case 0x3E: /* home key */
+#else
+ case 0x47: /* home key */
+#endif
cur_console->history_pos = cur_console->history_head;
#ifdef PC98
cur_console->his_atr_pos = cur_console->his_atr_head;
@@ -4233,8 +4796,11 @@ next_code:
history_to_screen(cur_console);
goto next_code;
- case SPCLKEY | FKEY | F(57): /* end key */
- remove_cutmarking(cur_console);
+#ifdef PC98
+ case 0x3F: /* help key */
+#else
+ case 0x4F: /* end key */
+#endif
cur_console->history_pos =
WRAPHIST(cur_console, cur_console->history_head,
cur_console->xsize*cur_console->ysize);
@@ -4246,65 +4812,183 @@ next_code:
history_to_screen(cur_console);
goto next_code;
- case SPCLKEY | FKEY | F(50): /* up arrow key */
- remove_cutmarking(cur_console);
+#ifdef PC98
+ case 0x3A: /* up arrow key */
+#else
+ case 0x48: /* up arrow key */
+#endif
if (history_up_line(cur_console))
- if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
goto next_code;
- case SPCLKEY | FKEY | F(58): /* down arrow key */
- remove_cutmarking(cur_console);
+#ifdef PC98
+ case 0x3D: /* down arrow key */
+#else
+ case 0x50: /* down arrow key */
+#endif
if (history_down_line(cur_console))
- if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
goto next_code;
- case SPCLKEY | FKEY | F(51): /* page up key */
- remove_cutmarking(cur_console);
+#ifdef PC98
+ case 0x36: /* roll up key */
+#else
+ case 0x49: /* page up key */
+#endif
for (i=0; i<cur_console->ysize; i++)
if (history_up_line(cur_console)) {
- if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
break;
}
goto next_code;
- case SPCLKEY | FKEY | F(59): /* page down key */
- remove_cutmarking(cur_console);
+#ifdef PC98
+ case 0x37: /* roll down key */
+#else
+ case 0x51: /* page down key */
+#endif
for (i=0; i<cur_console->ysize; i++)
if (history_down_line(cur_console)) {
- if (!(flags & SCGETC_CN))
- do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
break;
}
goto next_code;
}
}
- /*
- * Process and consume special keys here. Return a plain char code
- * or a char code with the META flag or a function key code.
- */
- if (c & RELKEY) {
- /* key released */
- /* goto next_code */
+ if (compose) {
+ switch (scancode) {
+ /* key pressed process it */
+ case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */
+ chr = (scancode - 0x40) + chr*10;
+ goto next_code;
+ case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */
+ chr = (scancode - 0x47) + chr*10;
+ goto next_code;
+ case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */
+ chr = (scancode - 0x4E) + chr*10;
+ goto next_code;
+ case 0x52: /* keypad 0 */
+ chr *= 10;
+ goto next_code;
+
+ /* key release, no interest here */
+ case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */
+ case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */
+ case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */
+ case 0xD2: /* keypad 0 */
+ goto next_code;
+
+ case 0x38: /* left alt key */
+ break;
+ default:
+ if (chr) {
+ compose = chr = 0;
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ goto next_code;
+ }
+ break;
+ }
+ }
+
+ state = (shfts ? 1 : 0 ) | (2 * (ctls ? 1 : 0)) | (4 * (alts ? 1 : 0));
+ if ((!agrs && (cur_console->status & ALKED))
+ || (agrs && !(cur_console->status & ALKED)))
+ keycode += ALTGR_OFFSET;
+ key = &key_map.key[keycode];
+ if ( ((key->flgs & FLAG_LOCK_C) && (cur_console->status & CLKED))
+ || ((key->flgs & FLAG_LOCK_N) && (cur_console->status & NLKED)) )
+ state ^= 1;
+
+ /* Check for make/break */
+ action = key->map[state];
+ if (scancode & 0x80) { /* key released */
+ if (key->spcl & (0x80>>state)) {
+ switch (action) {
+ case LSH:
+ shfts &= ~1;
+ break;
+ case RSH:
+ shfts &= ~2;
+ break;
+ case LCTR:
+ ctls &= ~1;
+ break;
+ case RCTR:
+ ctls &= ~2;
+ break;
+ case LALT:
+ alts &= ~1;
+ break;
+ case RALT:
+ alts &= ~2;
+ break;
+ case NLK:
+ nlkcnt = 0;
+ break;
+ case CLK:
+#ifdef PC98
+ cur_console->status &= ~CLKED;
+ update_leds(cur_console->status);
+#else
+ clkcnt = 0;
+#endif
+ break;
+ case SLK:
+ slkcnt = 0;
+ break;
+ case ASH:
+ agrs = 0;
+ break;
+ case ALK:
+ alkcnt = 0;
+ break;
+ case META:
+ metas = 0;
+ break;
+ }
+ }
+ if (chr && !compose) {
+ action = chr;
+ chr = 0;
+ return(action);
+ }
} else {
/* key pressed */
- if (c & SPCLKEY) {
- c &= ~SPCLKEY;
- switch (KEYCHAR(c)) {
+ if (key->spcl & (0x80>>state)) {
+ switch (action) {
/* LOCKING KEYS */
- case NLK: case CLK: case ALK:
+ case NLK:
+ if (!nlkcnt) {
+ nlkcnt++;
+ if (cur_console->status & NLKED)
+ cur_console->status &= ~NLKED;
+ else
+ cur_console->status |= NLKED;
+ update_leds(cur_console->status);
+ }
+ break;
+ case CLK:
+#ifdef PC98
+ cur_console->status |= CLKED;
+ update_leds(cur_console->status);
+#else
+ if (!clkcnt) {
+ clkcnt++;
+ if (cur_console->status & CLKED)
+ cur_console->status &= ~CLKED;
+ else
+ cur_console->status |= CLKED;
+ update_leds(cur_console->status);
+ }
+#endif
break;
case SLK:
- kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&f);
- if (f & SLKED) {
- cur_console->status |= SLKED;
- } else {
+ if (!slkcnt) {
+ slkcnt++;
if (cur_console->status & SLKED) {
cur_console->status &= ~SLKED;
- if (cur_console->status & BUFFER_SAVED) {
+ if (cur_console->status & BUFFER_SAVED){
int i;
u_short *ptr = cur_console->history_save;
#ifdef PC98
@@ -4328,12 +5012,11 @@ next_code:
cur_console->history +
cur_console->history_size)
#ifdef PC98
- {
- ptr = cur_console->history;
- ptr_a = cur_console->his_atr;
- }
-#else
+ {
+#endif
ptr = cur_console->history;
+#ifdef PC98
+ ptr_a = cur_console->his_atr; }
#endif
}
cur_console->status &= ~BUFFER_SAVED;
@@ -4346,64 +5029,73 @@ next_code:
}
scstart(VIRTUAL_TTY(get_scr_num()));
}
+ else
+ cur_console->status |= SLKED;
+ update_leds(cur_console->status);
+ }
+ break;
+ case ALK:
+ if (!alkcnt) {
+ alkcnt++;
+ if (cur_console->status & ALKED)
+ cur_console->status &= ~ALKED;
+ else
+ cur_console->status |= ALKED;
+ update_leds(cur_console->status);
}
break;
/* NON-LOCKING KEYS */
case NOP:
- case LSH: case RSH: case LCTR: case RCTR:
- case LALT: case RALT: case ASH: case META:
break;
-
- case BTAB:
- return c;
-
case SPSC:
/* force activatation/deactivation of the screen saver */
- if (!scrn_blanked) {
+ accents = 0;
+ if (scrn_blanked <= 0) {
run_scrn_saver = TRUE;
scrn_time_stamp -= scrn_blank_time;
}
-#if NSPLASH > 0
+#ifdef SC_SPLASH_SCREEN
if (cold) {
/*
* While devices are being probed, the screen saver need
* to be invoked explictly. XXX
*/
- if (scrn_blanked) {
+ if (scrn_blanked > 0) {
scsplash_stick(FALSE);
stop_scrn_saver(current_saver);
} else {
- if (!ISGRAPHSC(cur_console)) {
+ if ((cur_console->status & UNKNOWN_MODE) == 0) {
scsplash_stick(TRUE);
(*current_saver)(TRUE);
}
}
}
-#endif /* NSPLASH */
+#endif
break;
-
case RBT:
#ifndef SC_DISABLE_REBOOT
+ accents = 0;
shutdown_nice();
#endif
break;
-
-#if NAPM > 0
case SUSP:
+#if NAPM > 0
+ accents = 0;
apm_suspend(PMST_SUSPEND);
+#endif
break;
+
case STBY:
+#if NAPM > 0
+ accents = 0;
apm_suspend(PMST_STANDBY);
- break;
-#else
- case SUSP:
- case STBY:
- break;
#endif
+ break;
case DBG:
#ifdef DDB /* try to switch to console 0 */
+ accents = 0;
/*
* TRY to make sure the screen saver is stopped,
* and the screen is updated before switching to
@@ -4418,47 +5110,135 @@ next_code:
printf("No debugger in kernel\n");
#endif
break;
-
+ case LSH:
+ shfts |= 1;
+ break;
+ case RSH:
+ shfts |= 2;
+ break;
+ case LCTR:
+ ctls |= 1;
+ break;
+ case RCTR:
+ ctls |= 2;
+ break;
+ case LALT:
+ alts |= 1;
+ break;
+ case RALT:
+ alts |= 2;
+ break;
+ case ASH:
+ agrs = 1;
+ break;
+ case META:
+ metas = 1;
+ break;
case NEXT:
- this_scr = get_scr_num();
- for (i = this_scr + 1; i != this_scr; i = (i + 1)%MAXCONS) {
- struct tty *tp = VIRTUAL_TTY(i);
+ {
+ int next, this = get_scr_num();
+ accents = 0;
+ for (next = this+1; next != this; next = (next+1)%MAXCONS) {
+ struct tty *tp = VIRTUAL_TTY(next);
if (tp->t_state & TS_ISOPEN) {
- switch_scr(cur_console, i);
+ switch_scr(cur_console, next);
break;
}
}
+ }
break;
-
+ case BTAB:
+ accents = 0;
+ return(BKEY);
default:
- if (KEYCHAR(c) >= F_SCR && KEYCHAR(c) <= L_SCR) {
- switch_scr(cur_console, KEYCHAR(c) - F_SCR);
+ if (action >= F_ACC && action <= L_ACC) {
+ /* turn it into an index */
+ action -= F_ACC - 1;
+ if ((action > accent_map.n_accs)
+ || (accent_map.acc[action - 1].accchar == 0)) {
+ /*
+ * The index is out of range or pointing to an
+ * empty entry.
+ */
+ accents = 0;
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ }
+ /*
+ * If the same accent key has been hit twice,
+ * produce the accent char itself.
+ */
+ if (action == accents) {
+ action = accent_map.acc[accents - 1].accchar;
+ accents = 0;
+ if (metas)
+ action |= MKEY;
+ return (action);
+ }
+ /* remember the index and wait for the next key stroke */
+ accents = action;
+ break;
+ }
+ if (accents > 0) {
+ accents = 0;
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ }
+ if (action >= F_SCR && action <= L_SCR) {
+ switch_scr(cur_console, action - F_SCR);
break;
}
- /* assert(c & FKEY) */
- return c;
+ if (action >= F_FN && action <= L_FN)
+ action |= FKEY;
+ return(action);
}
- /* goto next_code */
- } else {
- /* regular keys (maybe MKEY is set) */
- return c;
}
- }
+ else {
+ if (accents) {
+ struct acc_t *acc;
+ int i;
+ acc = &accent_map.acc[accents - 1];
+ accents = 0;
+ /*
+ * If the accent key is followed by the space key,
+ * produce the accent char itself.
+ */
+ if (action == ' ') {
+ action = acc->accchar;
+ if (metas)
+ action |= MKEY;
+ return (action);
+ }
+ for (i = 0; i < NUM_ACCENTCHARS; ++i) {
+ if (acc->map[i][0] == 0) /* end of the map entry */
+ break;
+ if (acc->map[i][0] == action) {
+ action = acc->map[i][1];
+ if (metas)
+ action |= MKEY;
+ return (action);
+ }
+ }
+ do_bell(cur_console, BELL_PITCH, BELL_DURATION);
+ goto next_code;
+ }
+ if (metas)
+ action |= MKEY;
+ return(action);
+ }
+ }
goto next_code;
}
int
-scmmap(dev_t dev, vm_offset_t offset, int nprot)
+scmmap(dev_t dev, int offset, int nprot)
{
- struct tty *tp;
- struct scr_stat *scp;
-
- tp = scdevtotty(dev);
- if (!tp)
- return ENXIO;
- scp = sc_get_scr_stat(tp->t_dev);
- return (*vidsw[scp->ad]->mmap)(scp->adp, offset);
+#ifdef PC98
+ if (offset > 0x48000 - PAGE_SIZE)
+#else
+ if (offset > 0x20000 - PAGE_SIZE)
+#endif
+ return -1;
+ return i386_btop((VIDEOMEM + offset));
}
/*
@@ -4490,213 +5270,585 @@ mask2attr(struct term_stat *term)
return attr;
}
-static int
-save_kbd_state(scr_stat *scp)
+static void
+set_keyboard(int command, int data)
{
- int state;
- int error;
+#ifndef PC98
+ int s;
+
+ if (sc_kbdc == NULL)
+ return;
+
+ /* prevent the timeout routine from polling the keyboard */
+ if (!kbdc_lock(sc_kbdc, TRUE))
+ return;
- error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
- if (error == ENOIOCTL)
- error = ENODEV;
- if (error == 0) {
- scp->status &= ~LOCK_MASK;
- scp->status |= state;
+ /* disable the keyboard and mouse interrupt */
+ s = spltty();
+#if 0
+ c = get_controller_command_byte(sc_kbdc);
+ if ((c == -1)
+ || !set_controller_command_byte(sc_kbdc,
+ kbdc_get_device_mask(sc_kbdc),
+ KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
+ | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
+ /* CONTROLLER ERROR */
+ kbdc_lock(sc_kbdc, FALSE);
+ splx(s);
+ return;
}
- return error;
-}
+ /*
+ * Now that the keyboard controller is told not to generate
+ * the keyboard and mouse interrupts, call `splx()' to allow
+ * the other tty interrupts. The clock interrupt may also occur,
+ * but the timeout routine (`scrn_timer()') will be blocked
+ * by the lock flag set via `kbdc_lock()'
+ */
+ splx(s);
+#endif
-static int
-update_kbd_state(int new_bits, int mask)
-{
- int state;
- int error;
+ if (send_kbd_command_and_data(sc_kbdc, command, data) != KBD_ACK)
+ send_kbd_command(sc_kbdc, KBDC_ENABLE_KBD);
- if (mask != LOCK_MASK) {
- error = kbd_ioctl(kbd, KDGKBSTATE, (caddr_t)&state);
- if (error == ENOIOCTL)
- error = ENODEV;
- if (error)
- return error;
- state &= ~mask;
- state |= new_bits & mask;
- } else {
- state = new_bits & LOCK_MASK;
+#if 0
+ /* restore the interrupts */
+ if (!set_controller_command_byte(sc_kbdc,
+ kbdc_get_device_mask(sc_kbdc),
+ c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) {
+ /* CONTROLLER ERROR */
}
- error = kbd_ioctl(kbd, KDSKBSTATE, (caddr_t)&state);
- if (error == ENOIOCTL)
- error = ENODEV;
- return error;
+#else
+ splx(s);
+#endif
+ kbdc_lock(sc_kbdc, FALSE);
+#endif
}
-static int
-update_kbd_leds(int which)
+static void
+update_leds(int which)
{
- int error;
+#ifndef PC98
+ int s;
+ static u_char xlate_leds[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
- which &= LOCK_MASK;
- error = kbd_ioctl(kbd, KDSETLED, (caddr_t)&which);
- if (error == ENOIOCTL)
- error = ENODEV;
- return error;
+ /* replace CAPS led with ALTGR led for ALTGR keyboards */
+ if (key_map.n_keys > ALTGR_OFFSET) {
+ if (which & ALKED)
+ which |= CLKED;
+ else
+ which &= ~CLKED;
+ }
+
+ set_keyboard(KBDC_SET_LEDS, xlate_leds[which & LED_MASK]);
+#endif
}
-int
+void
set_mode(scr_stat *scp)
{
- video_info_t info;
-
- /* reject unsupported mode */
- if ((*vidsw[scp->ad]->get_info)(scp->adp, scp->mode, &info))
- return 1;
+ char special_modetable[MODE_PARAM_SIZE];
+ char *mp;
+ int s;
+ int i;
- /* if this vty is not currently showing, do nothing */
if (scp != cur_console)
- return 0;
+ return;
- /* setup video hardware for the given mode */
- (*vidsw[scp->ad]->set_mode)(scp->adp, scp->mode);
- Crtat = (u_short *)scp->adp->va_window;
+#ifndef PC98
+ /*
+ * even if mode switching is disabled, we can change back
+ * to the initial mode or the custom mode based on the initial
+ * mode if we have saved register values upon start-up.
+ */
+ mp = get_mode_param(scp, scp->mode);
+ if (mp == NULL)
+ return;
+ bcopy(mp, &special_modetable, sizeof(special_modetable));
+#endif
+ /* setup video hardware for the given mode */
#ifdef PC98
- if (scp->status & UNKNOWN_MODE) {
- while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */
- outb(0x62, 0xc); /* text off */
- outb(0xA2, 0xd); /* graphics on */
- } else {
- while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */
- outb(0x62, 0xd); /* text off */
- outb(0xA2, 0xc); /* graphics on */
- }
+#ifdef LINE30
+ switch (scp->mode) {
+ case M_PC98_80x25: /* VGA TEXT MODES */
+ initialize_gdc(T25_G400);
+ break;
+ case M_PC98_80x30:
+ initialize_gdc(T30_G400);
+ break;
+ default:
+ break;
+ }
#endif
+ if (scp->status & UNKNOWN_MODE) {
+ while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */
+ outb(0x62, 0xc); /* text off */
+ outb(0xA2, 0xd); /* graphics on */
+ } else {
+ while (!(inb(0x60) & 0x20)) {} /* V-SYNC wait */
+ outb(0x62, 0xd); /* text on */
+ outb(0xA2, 0xc); /* graphics off */
+ }
+#else /* IBM-PC */
+ switch (scp->mode) {
+ case M_VGA_C80x60: case M_VGA_M80x60:
+ special_modetable[2] = 0x08;
+ special_modetable[19] = 0x47;
+ goto special_480l;
- if (!(scp->status & GRAPHICS_MODE)) {
- /* load appropriate font */
- if (!(scp->status & PIXEL_MODE) && ISFONTAVAIL(scp->adp->va_flags)) {
- if (scp->font_size < 14) {
- if (fonts_loaded & FONT_8)
- copy_font(scp, LOAD, 8, font_8);
- } else if (scp->font_size >= 16) {
- if (fonts_loaded & FONT_16)
- copy_font(scp, LOAD, 16, font_16);
- } else {
- if (fonts_loaded & FONT_14)
- copy_font(scp, LOAD, 14, font_14);
- }
- /*
- * FONT KLUDGE:
- * This is an interim kludge to display correct font.
- * Always use the font page #0 on the video plane 2.
- * Somehow we cannot show the font in other font pages on
- * some video cards... XXX
- */
- (*vidsw[scp->ad]->show_font)(scp->adp, 0);
+ case M_VGA_C80x30: case M_VGA_M80x30:
+ special_modetable[19] = 0x4f;
+special_480l:
+ special_modetable[9] |= 0xc0;
+ special_modetable[16] = 0x08;
+ special_modetable[17] = 0x3e;
+ special_modetable[26] = 0xea;
+ special_modetable[28] = 0xdf;
+ special_modetable[31] = 0xe7;
+ special_modetable[32] = 0x04;
+ goto setup_mode;
+
+ case M_ENH_C80x43: case M_ENH_B80x43:
+ special_modetable[28] = 87;
+ goto special_80x50;
+
+ case M_VGA_C80x50: case M_VGA_M80x50:
+special_80x50:
+ special_modetable[2] = 8;
+ special_modetable[19] = 7;
+ goto setup_mode;
+
+ case M_VGA_C40x25: case M_VGA_C80x25:
+ case M_VGA_M80x25:
+ case M_B40x25: case M_C40x25:
+ case M_B80x25: case M_C80x25:
+ case M_ENH_B40x25: case M_ENH_C40x25:
+ case M_ENH_B80x25: case M_ENH_C80x25:
+ case M_EGAMONO80x25:
+
+setup_mode:
+ set_vgaregs(special_modetable);
+ scp->font_size = special_modetable[2];
+
+ /* set font type (size) */
+ if (scp->font_size < 14) {
+ if (fonts_loaded & FONT_8)
+ copy_font(LOAD, FONT_8, font_8);
+ i = 0x0a; /* font 2 */
+ } else if (scp->font_size >= 16) {
+ if (fonts_loaded & FONT_16)
+ copy_font(LOAD, FONT_16, font_16);
+ i = 0x00; /* font 0 */
+ } else {
+ if (fonts_loaded & FONT_14)
+ copy_font(LOAD, FONT_14, font_14);
+ i = 0x05; /* font 1 */
}
+ /*
+ * FONT KLUDGE:
+ * This is an interim kludge to display correct font.
+ * Always use the font page #0 on the video plane 2.
+ * Somehow we cannot show the font in other font pages on
+ * some video cards... XXX
+ */
+ i = 0x00;
+ s = splhigh();
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+ outb(TSIDX, 0x03); outb(TSREG, i);
+ outb(TSIDX, 0x00); outb(TSREG, 0x03);
+ splx(s);
+ if (flags & CHAR_CURSOR)
+ set_destructive_cursor(scp);
mark_all(scp);
- }
+ break;
- if (scp->status & PIXEL_MODE)
- generic_bzero((u_char *)(scp->adp->va_window),
- scp->xpixel*scp->ypixel/8);
- set_border(scp, scp->border);
+ case M_VGA_MODEX:
+ /* "unchain" the VGA mode */
+ special_modetable[5-1+0x04] &= 0xf7;
+ special_modetable[5-1+0x04] |= 0x04;
+ /* turn off doubleword mode */
+ special_modetable[10+0x14] &= 0xbf;
+ /* turn off word adressing */
+ special_modetable[10+0x17] |= 0x40;
+ /* set logical screen width */
+ special_modetable[10+0x13] = 80;
+ /* set 240 lines */
+ special_modetable[10+0x11] = 0x2c;
+ special_modetable[10+0x06] = 0x0d;
+ special_modetable[10+0x07] = 0x3e;
+ special_modetable[10+0x10] = 0xea;
+ special_modetable[10+0x11] = 0xac;
+ special_modetable[10+0x12] = 0xdf;
+ special_modetable[10+0x15] = 0xe7;
+ special_modetable[10+0x16] = 0x06;
+ /* set vertical sync polarity to reflect aspect ratio */
+ special_modetable[9] = 0xe3;
+ goto setup_grmode;
-#ifndef PC98
- /* move hardware cursor out of the way */
- (*vidsw[scp->ad]->set_hw_cursor)(scp->adp, -1, -1);
-#endif
+ case M_BG320: case M_CG320: case M_BG640:
+ case M_CG320_D: case M_CG640_E:
+ case M_CG640x350: case M_ENH_CG640:
+ case M_BG640x480: case M_CG640x480: case M_VGA_CG320:
- return 0;
+setup_grmode:
+ set_vgaregs(special_modetable);
+ scp->font_size = FONT_NONE;
+ break;
+
+ default:
+ /* call user defined function XXX */
+ break;
+ }
+#endif /* PC98 */
+
+ /* set border color for this (virtual) console */
+ set_border(scp->border);
+ return;
}
void
-set_border(scr_stat *scp, int color)
+set_border(u_char color)
{
+ switch (crtc_type) {
+#ifdef PC98
+ case KD_PC98:
+ outb(0x6c, color << 4);
+ break;
+#else
+ case KD_EGA:
+ case KD_VGA:
+ inb(crtc_addr + 6); /* reset flip-flop */
+ outb(ATC, 0x31); outb(ATC, color);
+ break;
+ case KD_CGA:
+ outb(crtc_addr + 5, color & 0x0f); /* color select register */
+ break;
+ case KD_MONO:
+ case KD_HERCULES:
+#endif
+ default:
+ break;
+ }
+}
+
#ifndef PC98
- u_char *p;
- int xoff;
- int yoff;
- int xlen;
- int ylen;
+static void
+set_vgaregs(char *modetable)
+{
+ int i, s = splhigh();
+
+ outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
+ for (i=0; i<4; i++) { /* program sequencer */
+ outb(TSIDX, i+1);
+ outb(TSREG, modetable[i+5]);
+ }
+ outb(MISC, modetable[9]); /* set dot-clock */
+ outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
+ outb(crtc_addr, 0x11);
+ outb(crtc_addr+1, inb(crtc_addr+1) & 0x7F);
+ for (i=0; i<25; i++) { /* program crtc */
+ outb(crtc_addr, i);
+ if (i == 14 || i == 15) /* no hardware cursor */
+ outb(crtc_addr+1, 0xff);
+ else
+ outb(crtc_addr+1, modetable[i+10]);
+ }
+ inb(crtc_addr+6); /* reset flip-flop */
+ for (i=0; i<20; i++) { /* program attribute ctrl */
+ outb(ATC, i);
+ outb(ATC, modetable[i+35]);
+ }
+ for (i=0; i<9; i++) { /* program graph data ctrl */
+ outb(GDCIDX, i);
+ outb(GDCREG, modetable[i+55]);
+ }
+ inb(crtc_addr+6); /* reset flip-flop */
+ outb(ATC, 0x20); /* enable palette */
+ splx(s);
+}
+
+static void
+read_vgaregs(char *buf)
+{
+ int i, j;
+ int s;
+
+ bzero(buf, MODE_PARAM_SIZE);
+
+ s = splhigh();
+
+ outb(TSIDX, 0x00); outb(TSREG, 0x01); /* stop sequencer */
+ for (i=0, j=5; i<4; i++) {
+ outb(TSIDX, i+1);
+ buf[j++] = inb(TSREG);
+ }
+ buf[9] = inb(MISC + 10); /* dot-clock */
+ outb(TSIDX, 0x00); outb(TSREG, 0x03); /* start sequencer */
+
+ for (i=0, j=10; i<25; i++) { /* crtc */
+ outb(crtc_addr, i);
+ buf[j++] = inb(crtc_addr+1);
+ }
+ for (i=0, j=35; i<20; i++) { /* attribute ctrl */
+ inb(crtc_addr+6); /* reset flip-flop */
+ outb(ATC, i);
+ buf[j++] = inb(ATC + 1);
+ }
+ for (i=0, j=55; i<9; i++) { /* graph data ctrl */
+ outb(GDCIDX, i);
+ buf[j++] = inb(GDCREG);
+ }
+ inb(crtc_addr+6); /* reset flip-flop */
+ outb(ATC, 0x20); /* enable palette */
+
+ buf[0] = *(char *)pa_to_va(0x44a); /* COLS */
+ buf[1] = *(char *)pa_to_va(0x484); /* ROWS */
+ buf[2] = *(char *)pa_to_va(0x485); /* POINTS */
+ buf[3] = *(char *)pa_to_va(0x44c);
+ buf[4] = *(char *)pa_to_va(0x44d);
+
+ splx(s);
+}
+
+static int
+comp_vgaregs(u_char *buf1, u_char *buf2)
+{
+ static struct {
+ u_char mask;
+ } params[MODE_PARAM_SIZE] = {
+ 0xff, 0x00, 0xff, /* COLS, ROWS, POINTS */
+ 0xff, 0xff, /* page length */
+ 0xfe, 0xff, 0xff, 0xff, /* sequencer registers */
+ 0xf3, /* misc register */
+ 0xff, 0xff, 0xff, 0x7f, 0xff, /* CRTC */
+ 0xff, 0xff, 0xff, 0x7f, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xff, 0x7f, 0xff, 0xff,
+ 0x7f, 0xff, 0xff, 0xef, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, /* attribute controller registers */
+ 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xf0,
+ 0xff, 0xff, 0xff, 0xff, 0xff, /* GDC register */
+ 0xff, 0xff, 0xff, 0xff,
+ };
+ int identical = TRUE;
int i;
- (*vidsw[scp->ad]->set_border)(scp->adp, color);
+ for (i = 0; i < sizeof(params)/sizeof(params[0]); ++i) {
+ if (params[i].mask == 0) /* don't care */
+ continue;
+ if ((buf1[i] & params[i].mask) != (buf2[i] & params[i].mask))
+ return COMP_DIFFERENT;
+ if (buf1[i] != buf2[i])
+ identical = FALSE;
+ }
+ return (identical) ? COMP_IDENTICAL : COMP_SIMILAR;
- if (scp->status & PIXEL_MODE) {
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, 0x0003); /* data rotate/function select */
- outw(GDCIDX, 0x0f01); /* set/reset enable */
- outw(GDCIDX, 0xff08); /* bit mask */
- outw(GDCIDX, (color << 8) | 0x00); /* set/reset */
- p = (u_char *)(scp->adp->va_window);
- xoff = scp->xoff;
- yoff = scp->yoff*scp->font_size;
- xlen = scp->xpixel/8;
- ylen = scp->ysize*scp->font_size;
- if (yoff > 0) {
- generic_bzero(p, xlen*yoff);
- generic_bzero(p + xlen*(yoff + ylen),
- xlen*scp->ypixel - xlen*(yoff + ylen));
- }
- if (xoff > 0) {
- for (i = 0; i < ylen; ++i) {
- generic_bzero(p + xlen*(yoff + i), xoff);
- generic_bzero(p + xlen*(yoff + i) + xoff + scp->xsize,
- xlen - xoff - scp->xsize);
- }
- }
- outw(GDCIDX, 0x0000); /* set/reset */
- outw(GDCIDX, 0x0001); /* set/reset enable */
+#if 0
+ for(i = 0; i < 20; ++i) {
+ if (*buf1++ != *buf2++)
+ return COMP_DIFFERENT;
}
-#else /* PC98 */
- (*vidsw[scp->ad]->set_border)(scp->adp, color);
-#endif /* PC98 */
+ buf1 += 2; /* skip the cursor shape */
+ buf2 += 2;
+ for(i = 22; i < 24; ++i) {
+ if (*buf1++ != *buf2++)
+ return COMP_DIFFERENT;
+ }
+ buf1 += 2; /* skip the cursor position */
+ buf2 += 2;
+ for(i = 26; i < MODE_PARAM_SIZE; ++i) {
+ if (*buf1++ != *buf2++)
+ return COMP_DIFFERENT;
+ }
+ return COMP_IDENTICAL;
+#endif
}
-void
-copy_font(scr_stat *scp, int operation, int font_size, u_char *buf)
+static void
+dump_vgaregs(u_char *buf)
{
- /*
- * FONT KLUDGE:
- * This is an interim kludge to display correct font.
- * Always use the font page #0 on the video plane 2.
- * Somehow we cannot show the font in other font pages on
- * some video cards... XXX
- */
+ int i;
+
+ for(i = 0; i < MODE_PARAM_SIZE;) {
+ printf("%02x ", buf[i]);
+ if ((++i % 16) == 0)
+ printf("\n");
+ }
+}
+
+static void
+set_font_mode(u_char *buf)
+{
+ int s = splhigh();
+
font_loading_in_progress = TRUE;
- if (operation == LOAD) {
- (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, buf, 0, 256);
- if (sc_flags & CHAR_CURSOR)
- set_destructive_cursor(scp);
- } else if (operation == SAVE) {
- (*vidsw[scp->ad]->save_font)(scp->adp, 0, font_size, buf, 0, 256);
+
+ /* save register values */
+ outb(TSIDX, 0x02); buf[0] = inb(TSREG);
+ outb(TSIDX, 0x04); buf[1] = inb(TSREG);
+ outb(GDCIDX, 0x04); buf[2] = inb(GDCREG);
+ outb(GDCIDX, 0x05); buf[3] = inb(GDCREG);
+ outb(GDCIDX, 0x06); buf[4] = inb(GDCREG);
+ inb(crtc_addr + 6);
+ outb(ATC, 0x10); buf[5] = inb(ATC + 1);
+
+ /* setup vga for loading fonts */
+ inb(crtc_addr+6); /* reset flip-flop */
+ outb(ATC, 0x10); outb(ATC, buf[5] & ~0x01);
+ inb(crtc_addr+6); /* reset flip-flop */
+ outb(ATC, 0x20); /* enable palette */
+
+#if SLOW_VGA
+#ifndef SC_BAD_FLICKER
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+#endif
+ outb(TSIDX, 0x02); outb(TSREG, 0x04);
+ outb(TSIDX, 0x04); outb(TSREG, 0x07);
+#ifndef SC_BAD_FLICKER
+ outb(TSIDX, 0x00); outb(TSREG, 0x03);
+#endif
+ outb(GDCIDX, 0x04); outb(GDCREG, 0x02);
+ outb(GDCIDX, 0x05); outb(GDCREG, 0x00);
+ outb(GDCIDX, 0x06); outb(GDCREG, 0x04);
+#else
+#ifndef SC_BAD_FLICKER
+ outw(TSIDX, 0x0100);
+#endif
+ outw(TSIDX, 0x0402);
+ outw(TSIDX, 0x0704);
+#ifndef SC_BAD_FLICKER
+ outw(TSIDX, 0x0300);
+#endif
+ outw(GDCIDX, 0x0204);
+ outw(GDCIDX, 0x0005);
+ outw(GDCIDX, 0x0406); /* addr = a0000, 64kb */
+#endif
+ splx(s);
+}
+
+static void
+set_normal_mode(u_char *buf)
+{
+ char *modetable;
+ int s = splhigh();
+
+ /* setup vga for normal operation mode again */
+ inb(crtc_addr+6); /* reset flip-flop */
+ outb(ATC, 0x10); outb(ATC, buf[5]);
+ inb(crtc_addr+6); /* reset flip-flop */
+ outb(ATC, 0x20); /* enable palette */
+
+#if SLOW_VGA
+#ifndef SC_BAD_FLICKER
+ outb(TSIDX, 0x00); outb(TSREG, 0x01);
+#endif
+ outb(TSIDX, 0x02); outb(TSREG, buf[0]);
+ outb(TSIDX, 0x04); outb(TSREG, buf[1]);
+#ifndef SC_BAD_FLICKER
+ outb(TSIDX, 0x00); outb(TSREG, 0x03);
+#endif
+ outb(GDCIDX, 0x04); outb(GDCREG, buf[2]);
+ outb(GDCIDX, 0x05); outb(GDCREG, buf[3]);
+ if (crtc_addr == MONO_BASE) {
+ outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x08);
+ } else {
+ outb(GDCIDX, 0x06); outb(GDCREG,(buf[4] & 0x03) | 0x0c);
}
+#else
+#ifndef SC_BAD_FLICKER
+ outw(TSIDX, 0x0100);
+#endif
+ outw(TSIDX, 0x0002 | (buf[0] << 8));
+ outw(TSIDX, 0x0004 | (buf[1] << 8));
+#ifndef SC_BAD_FLICKER
+ outw(TSIDX, 0x0300);
+#endif
+ outw(GDCIDX, 0x0004 | (buf[2] << 8));
+ outw(GDCIDX, 0x0005 | (buf[3] << 8));
+ if (crtc_addr == MONO_BASE)
+ outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x08)<<8));
+ else
+ outw(GDCIDX, 0x0006 | (((buf[4] & 0x03) | 0x0c)<<8));
+#endif
+
font_loading_in_progress = FALSE;
+ splx(s);
+}
+#endif
+
+void
+copy_font(int operation, int font_type, char* font_image)
+{
+#ifndef PC98
+ int ch, line, segment, fontsize;
+ u_char buf[PARAM_BUFSIZE];
+ u_char val;
+
+ switch (font_type) {
+ default:
+ case FONT_8:
+ segment = 0x8000;
+ fontsize = 8;
+ break;
+ case FONT_14:
+ segment = 0x4000;
+ fontsize = 14;
+ break;
+ case FONT_16:
+ segment = 0x0000;
+ fontsize = 16;
+ break;
+ }
+ /*
+ * FONT KLUDGE
+ * Always use the font page #0. XXX
+ */
+ segment = 0x0000;
+ outb(TSIDX, 0x01); val = inb(TSREG); /* disable screen */
+ outb(TSIDX, 0x01); outb(TSREG, val | 0x20);
+ set_font_mode(buf);
+ for (ch=0; ch < 256; ch++)
+ for (line=0; line < fontsize; line++)
+ if (operation)
+ *(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line) =
+ font_image[(ch*fontsize)+line];
+ else
+ font_image[(ch*fontsize)+line] =
+ *(char *)pa_to_va(VIDEOMEM+(segment)+(ch*32)+line);
+ set_normal_mode(buf);
+ outb(TSIDX, 0x01); outb(TSREG, val & 0xDF); /* enable screen */
+#endif
}
static void
set_destructive_cursor(scr_stat *scp)
{
#ifndef PC98
+ u_char buf[PARAM_BUFSIZE];
u_char cursor[32];
- u_char *font_buffer;
- int font_size;
- int crtc_addr;
+ caddr_t address;
int i;
-
- if (!ISFONTAVAIL(scp->adp->va_flags)
- || (scp->status & (GRAPHICS_MODE | PIXEL_MODE)))
- return;
+ char *font_buffer;
if (scp->font_size < 14) {
font_buffer = font_8;
- font_size = 8;
- } else if (scp->font_size >= 16) {
+ address = (caddr_t)VIDEOMEM + 0x8000;
+ }
+ else if (scp->font_size >= 16) {
font_buffer = font_16;
- font_size = 16;
- } else {
+ address = (caddr_t)VIDEOMEM;
+ }
+ else {
font_buffer = font_14;
- font_size = 14;
+ address = (caddr_t)VIDEOMEM + 0x4000;
}
+ /*
+ * FONT KLUDGE
+ * Always use the font page #0. XXX
+ */
+ address = (caddr_t)VIDEOMEM;
if (scp->status & MOUSE_VISIBLE) {
if ((scp->cursor_saveunder & 0xff) == SC_MOUSE_CHAR)
@@ -4719,24 +5871,14 @@ set_destructive_cursor(scr_stat *scp)
(scp->cursor_start >= scp->font_size && i == scp->font_size - 1))
cursor[i] |= 0xff;
#if 1
- crtc_addr = scp->adp->va_crtc_addr;
while (!(inb(crtc_addr+6) & 0x08)) /* wait for vertical retrace */ ;
#endif
- font_loading_in_progress = TRUE;
- (*vidsw[scp->ad]->load_font)(scp->adp, 0, font_size, cursor, DEAD_CHAR, 1);
- font_loading_in_progress = FALSE;
+ set_font_mode(buf);
+ generic_bcopy(cursor, (char *)pa_to_va(address) + DEAD_CHAR * 32, 32);
+ set_normal_mode(buf);
#endif
}
-void
-sc_move_mouse(scr_stat *scp, int x, int y)
-{
- scp->mouse_xpos = x;
- scp->mouse_ypos = y;
- scp->mouse_pos = scp->mouse_oldpos =
- scp->scr_buf + (y / scp->font_size) * scp->xsize + x / 8;
-}
-
static void
set_mouse_pos(scr_stat *scp)
{
@@ -4746,7 +5888,7 @@ set_mouse_pos(scr_stat *scp)
scp->mouse_xpos = 0;
if (scp->mouse_ypos < 0)
scp->mouse_ypos = 0;
- if (!ISTEXTSC(scp)) {
+ if (scp->status & UNKNOWN_MODE) {
if (scp->mouse_xpos > scp->xpixel-1)
scp->mouse_xpos = scp->xpixel-1;
if (scp->mouse_ypos > scp->ypixel-1)
@@ -4979,28 +6121,35 @@ draw_mouse_image(scr_stat *scp)
#ifdef PC98
*(Atrat + (scp->mouse_pos - scp->scr_buf)) ^= 0x4; /* reverse bit */
#else
+ caddr_t address;
+ int i;
+ char *font_buffer;
+ u_char buf[PARAM_BUFSIZE];
u_short buffer[32];
u_short xoffset, yoffset;
- u_short *crt_pos = (u_short *)(scp->adp->va_window)
- + (scp->mouse_pos - scp->scr_buf);
- u_char *font_buffer;
- int font_size;
- int crtc_addr;
- int i;
+ u_short *crt_pos = Crtat + (scp->mouse_pos - scp->scr_buf);
+ int font_size = scp->font_size;
- if (scp->font_size < 14) {
+ if (font_size < 14) {
font_buffer = font_8;
- font_size = 8;
- } else if (scp->font_size >= 16) {
+ address = (caddr_t)VIDEOMEM + 0x8000;
+ }
+ else if (font_size >= 16) {
font_buffer = font_16;
- font_size = 16;
- } else {
+ address = (caddr_t)VIDEOMEM;
+ }
+ else {
font_buffer = font_14;
- font_size = 14;
+ address = (caddr_t)VIDEOMEM + 0x4000;
}
+ /*
+ * FONT KLUDGE
+ * Always use the font page #0. XXX
+ */
+ address = (caddr_t)VIDEOMEM;
xoffset = scp->mouse_xpos % 8;
- yoffset = scp->mouse_ypos % scp->font_size;
+ yoffset = scp->mouse_ypos % font_size;
/* prepare mousepointer char's bitmaps */
bcopy(font_buffer + ((*(scp->mouse_pos) & 0xff) * font_size),
@@ -5029,19 +6178,15 @@ draw_mouse_image(scr_stat *scp)
scp->mouse_cursor[i+96] = buffer[i+font_size] & 0xff;
}
#endif
-
scp->mouse_oldpos = scp->mouse_pos;
#ifndef PC98
#if 1
/* wait for vertical retrace to avoid jitter on some videocards */
- crtc_addr = scp->adp->va_crtc_addr;
while (!(inb(crtc_addr+6) & 0x08)) /* idle */ ;
#endif
- font_loading_in_progress = TRUE;
- (*vidsw[scp->ad]->load_font)(scp->adp, 0, 32, scp->mouse_cursor,
- SC_MOUSE_CHAR, 4);
- font_loading_in_progress = FALSE;
-
+ set_font_mode(buf);
+ generic_bcopy(scp->mouse_cursor, (char *)pa_to_va(address) + SC_MOUSE_CHAR * 32, 128);
+ set_normal_mode(buf);
*(crt_pos) = (*(scp->mouse_pos) & 0xff00) | SC_MOUSE_CHAR;
*(crt_pos+scp->xsize) =
(*(scp->mouse_pos + scp->xsize) & 0xff00) | (SC_MOUSE_CHAR + 2);
@@ -5060,16 +6205,10 @@ draw_mouse_image(scr_stat *scp)
static void
remove_mouse_image(scr_stat *scp)
{
- u_short *crt_pos;
-
- if (!ISTEXTSC(scp))
- return;
-
#ifdef PC98
- crt_pos = Atrat + (scp->mouse_oldpos - scp->scr_buf);
+ u_short *crt_pos = Atrat + (scp->mouse_oldpos - scp->scr_buf);
#else
- crt_pos = (u_short *)(scp->adp->va_window)
- + (scp->mouse_oldpos - scp->scr_buf);
+ u_short *crt_pos = Crtat + (scp->mouse_oldpos - scp->scr_buf);
#endif
#ifdef PC98
@@ -5089,17 +6228,15 @@ remove_mouse_image(scr_stat *scp)
static void
draw_cutmarking(scr_stat *scp)
{
- u_short *crt_pos;
u_short *ptr;
u_short och, nch;
+ for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) {
#ifdef PC98
- crt_pos = Atrat;
+ nch = och = *(Atrat + (ptr - scp->scr_buf));
#else
- crt_pos = (u_short *)(scp->adp->va_window);
+ nch = och = *(Crtat + (ptr - scp->scr_buf));
#endif
- for (ptr=scp->scr_buf; ptr<=(scp->scr_buf+(scp->xsize*scp->ysize)); ptr++) {
- nch = och = *(crt_pos + (ptr - scp->scr_buf));
/* are we outside the selected area ? */
if ( ptr < (scp->mouse_cut_start > scp->mouse_cut_end ?
scp->mouse_cut_end : scp->mouse_cut_start) ||
@@ -5124,16 +6261,20 @@ draw_cutmarking(scr_stat *scp)
if (ptr != scp->cursor_pos)
nch = (och & 0x88ff) | (*ptr & 0x7000)>>4 | (*ptr & 0x0700)<<4;
else {
- if (sc_flags & CHAR_CURSOR)
+ if (flags & CHAR_CURSOR)
nch = (och & 0x88ff)|(*ptr & 0x7000)>>4|(*ptr & 0x0700)<<4;
else
- if (!(sc_flags & BLINK_CURSOR))
+ if (!(flags & BLINK_CURSOR))
nch = (och & 0xff) | (*ptr & 0xff00);
}
#endif
}
if (nch != och)
- *(crt_pos + (ptr - scp->scr_buf)) = nch;
+#ifdef PC98
+ *(Atrat + (ptr - scp->scr_buf)) = nch;
+#else
+ *(Crtat + (ptr - scp->scr_buf)) = nch;
+#endif
}
}
@@ -5146,15 +6287,43 @@ remove_cutmarking(scr_stat *scp)
}
static void
+save_palette(void)
+{
+#ifndef PC98
+ int i;
+
+ outb(PALRADR, 0x00);
+ for (i=0x00; i<0x300; i++)
+ palette[i] = inb(PALDATA);
+ inb(crtc_addr+6); /* reset flip/flop */
+#endif
+}
+
+void
+load_palette(char *palette)
+{
+#ifndef PC98
+ int i;
+
+ outb(PIXMASK, 0xFF); /* no pixelmask */
+ outb(PALWADR, 0x00);
+ for (i=0x00; i<0x300; i++)
+ outb(PALDATA, palette[i]);
+ inb(crtc_addr+6); /* reset flip/flop */
+ outb(ATC, 0x20); /* enable palette */
+#endif
+}
+
+static void
do_bell(scr_stat *scp, int pitch, int duration)
{
if (cold || shutdown_in_progress)
return;
- if (scp != cur_console && (sc_flags & QUIET_BELL))
+ if (scp != cur_console && (flags & QUIET_BELL))
return;
- if (sc_flags & VISUAL_BELL) {
+ if (flags & VISUAL_BELL) {
if (blink_in_progress)
return;
blink_in_progress = 4;
@@ -5173,7 +6342,7 @@ blink_screen(void *arg)
{
scr_stat *scp = arg;
- if (!ISTEXTSC(scp) || (blink_in_progress <= 1)) {
+ if ((scp->status & UNKNOWN_MODE) || (blink_in_progress <= 1)) {
blink_in_progress = FALSE;
mark_all(scp);
if (delayed_next_scr)
@@ -5183,26 +6352,22 @@ blink_screen(void *arg)
#ifdef PC98
if (blink_in_progress & 1){
fillw(scr_map[0x20],
- (u_short *)(scp->adp->va_window),
- scp->xsize * scp->ysize);
+ Crtat, scp->xsize * scp->ysize);
fillw(at2pc98(kernel_default.std_color),
Atrat, scp->xsize * scp->ysize);
} else {
fillw(scr_map[0x20],
- (u_short *)(scp->adp->va_window),
- scp->xsize * scp->ysize);
+ Crtat, scp->xsize * scp->ysize);
fillw(at2pc98(kernel_default.rev_color),
Atrat, scp->xsize * scp->ysize);
}
#else
if (blink_in_progress & 1)
fillw(kernel_default.std_color | scr_map[0x20],
- (u_short *)(scp->adp->va_window),
- scp->xsize * scp->ysize);
+ Crtat, scp->xsize * scp->ysize);
else
fillw(kernel_default.rev_color | scr_map[0x20],
- (u_short *)(scp->adp->va_window),
- scp->xsize * scp->ysize);
+ Crtat, scp->xsize * scp->ysize);
#endif
blink_in_progress--;
timeout(blink_screen, scp, hz / 10);
@@ -5212,105 +6377,225 @@ blink_screen(void *arg)
void
sc_bcopy(scr_stat *scp, u_short *p, int from, int to, int mark)
{
-#ifdef PC98
- if (ISTEXTSC(scp))
- generic_bcopy(p + from, (u_short *)(scp->adp->va_window) + from,
- (to - from + 1)*sizeof(u_short));
-#else /* PC98 */
- u_char *font;
- u_char volatile *d;
- u_char *e;
- u_char *f;
- int font_size;
- int line_length;
- int xsize;
- u_short bg;
- int i, j;
- u_char c;
+ if (!VESA_MODE(scp->mode)) {
+ generic_bcopy(p+from, Crtat+from, (to-from+1)*sizeof (u_short));
+ } else if (scp->mode == 0x102) {
+ u_char *d, *e;
+ int i,j;
- if (ISTEXTSC(scp)) {
- generic_bcopy(p + from, (u_short *)(scp->adp->va_window) + from,
- (to - from + 1)*sizeof(u_short));
- } else /* if ISPIXELSC(scp) */ {
if (mark)
- mark = 255;
- font_size = scp->font_size;
- if (font_size < 14)
- font = font_8;
- else if (font_size >= 16)
- font = font_16;
- else
- font = font_14;
- line_length = scp->xpixel/8;
- xsize = scp->xsize;
- d = (u_char *)(scp->adp->va_window)
- + scp->xoff + scp->yoff*font_size*line_length
- + (from%xsize) + font_size*line_length*(from/xsize);
-
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, 0x0003); /* data rotate/function select */
- outw(GDCIDX, 0x0f01); /* set/reset enable */
- bg = -1;
+ mark = 255;
+ d = (u_char *)Crtat;
+ d += 10 + 6*16*100 + (from%80) + 16*100*(from/80);
for (i = from ; i <= to ; i++) {
- /* set background color in EGA/VGA latch */
- if (bg != (p[i] & 0xf000)) {
- bg = (p[i] & 0xf000);
- outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
- outw(GDCIDX, 0xff08); /* bit mask */
- *d = 0;
- c = *d; /* set the background color in the latch */
- }
- /* foreground color */
- outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
- e = (u_char *)d;
- f = &font[(p[i] & 0x00ff)*font_size];
- for (j = 0 ; j < font_size; j++, f++) {
- outw(GDCIDX, ((*f^mark) << 8) | 0x08); /* bit mask */
- *e = 0;
- e += line_length;
+ e = d;
+ for (j = 0 ; j < 16; j++) {
+ *e = mark^font_16[(p[i]&0xff)*16+j];
+ e+=100;
}
d++;
- if ((i % xsize) == xsize - 1)
- d += scp->xoff*2 + (font_size - 1)*line_length;
+ if ((i % 80) == 79)
+ d += 20 + 15*100;
}
- outw(GDCIDX, 0x0000); /* set/reset */
- outw(GDCIDX, 0x0001); /* set/reset enable */
- outw(GDCIDX, 0xff08); /* bit mask */
+ }
+}
-#if 0 /* VGA only */
- outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
- outw(GDCIDX, 0x0003); /* data rotate/function select */
- outw(GDCIDX, 0x0f01); /* set/reset enable */
- outw(GDCIDX, 0xff08); /* bit mask */
- bg = -1;
- for (i = from ; i <= to ; i++) {
- /* set background color in EGA/VGA latch */
- if (bg != (p[i] & 0xf000)) {
- bg = (p[i] & 0xf000);
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, (bg >> 4) | 0x00); /* set/reset */
- *d = 0;
- c = *d; /* set the background color in the latch */
- outw(GDCIDX, 0x0305); /* read mode 0, write mode 3 */
- }
- /* foreground color */
- outw(GDCIDX, (p[i] & 0x0f00) | 0x00); /* set/reset */
- e = (u_char *)d;
- f = &font[(p[i] & 0x00ff)*font_size];
- for (j = 0 ; j < font_size; j++, f++) {
- *e = *f^mark;
- e += line_length;
- }
- d++;
- if ((i % xsize) == xsize - 1)
- d += scp->xoff*2 + (font_size - 1)*line_length;
+#ifdef SC_SPLASH_SCREEN
+
+static void
+scsplash_init(void)
+{
+#ifndef PC98
+ /*
+ * We currently assume the splash screen always use
+ * VGA_CG320 mode and abort installation if this mode is not
+ * supported with this video card. XXX
+ */
+ if (crtc_type != KD_VGA || get_mode_param(cur_console, M_VGA_CG320) == NULL)
+ return;
+#endif
+
+ if (splash_load() == 0 && add_scrn_saver(scsplash) == 0) {
+ default_saver = scsplash;
+ scrn_blank_time = DEFAULT_BLANKTIME;
+ run_scrn_saver = TRUE;
+ if (!(boothowto & RB_CONFIG)) {
+ scsplash_stick(TRUE);
+ scsplash(TRUE);
}
- outw(GDCIDX, 0x0005); /* read mode 0, write mode 0 */
- outw(GDCIDX, 0x0000); /* set/reset */
- outw(GDCIDX, 0x0001); /* set/reset enable */
-#endif /* 0 */
}
-#endif /* PC98 */
}
+static void
+scsplash(int show)
+{
+ if (show)
+ splash(TRUE);
+ else if (!sticky_splash)
+ splash(FALSE);
+}
+
+#endif /* SC_SPLASH_SCREEN */
+
+#if defined(PC98) && defined(LINE30) /* 30line */
+
+static void master_gdc_cmd(unsigned int cmd)
+{
+ while ( (inb(0x60) & 2) != 0);
+ outb(0x62, cmd);
+}
+
+static void master_gdc_prm(unsigned int pmtr)
+{
+ while ( (inb(0x60) & 2) != 0);
+ outb(0x60, pmtr);
+}
+
+static void master_gdc_word_prm(unsigned int wpmtr)
+{
+ master_gdc_prm(wpmtr & 0x00ff);
+ master_gdc_prm((wpmtr >> 8) & 0x00ff);
+}
+
+static void master_gdc_fifo_empty(void)
+{
+ while ( (inb(0x60) & 4) == 0);
+}
+
+static void master_gdc_wait_vsync(void)
+{
+ while ( (inb(0x60) & 0x20) != 0);
+ while ( (inb(0x60) & 0x20) == 0);
+}
+
+static void gdc_cmd(unsigned int cmd)
+{
+ while ( (inb(0xa0) & 2) != 0);
+ outb( 0xa2, cmd);
+}
+
+static void gdc_prm(unsigned int pmtr)
+{
+ while ( (inb(0xa0) & 2) != 0);
+ outb( 0xa0, pmtr);
+}
+
+static void gdc_word_prm(unsigned int wpmtr)
+{
+ gdc_prm(wpmtr & 0x00ff);
+ gdc_prm((wpmtr >> 8) & 0x00ff);
+}
+
+static void gdc_fifo_empty(void)
+{
+ while ( (inb(0xa0) & 0x04) == 0);
+}
+
+static void gdc_wait_vsync(void)
+{
+ while ( (inb(0xa0) & 0x20) != 0);
+ while ( (inb(0xa0) & 0x20) == 0);
+}
+
+static int check_gdc_clock(void)
+{
+ if ((inb(0x31) & 0x80) == 0){
+ return _5MHZ;
+ } else {
+ return _2_5MHZ;
+ }
+}
+
+static void initialize_gdc(unsigned int mode)
+{
+ /* start 30line initialize */
+ int m_mode,s_mode,gdc_clock;
+ gdc_clock = check_gdc_clock();
+
+ if (mode == T25_G400){
+ m_mode = _25L;
+ }else{
+ m_mode = _30L;
+ }
+
+ s_mode = 2*mode+gdc_clock;
+
+ gdc_INFO = m_mode;
+
+ master_gdc_cmd(_GDC_RESET);
+ master_gdc_cmd(_GDC_MASTER);
+ gdc_cmd(_GDC_RESET);
+ gdc_cmd(_GDC_SLAVE);
+
+ /* GDC Master */
+ master_gdc_cmd(_GDC_SYNC);
+ master_gdc_prm(0x00); /* flush less */ /* text & graph */
+ master_gdc_prm(master_param[m_mode][GDC_CR]);
+ master_gdc_word_prm(((master_param[m_mode][GDC_HFP] << 10)
+ + (master_param[m_mode][GDC_VS] << 5)
+ + master_param[m_mode][GDC_HS]));
+ master_gdc_prm(master_param[m_mode][GDC_HBP]);
+ master_gdc_prm(master_param[m_mode][GDC_VFP]);
+ master_gdc_word_prm(((master_param[m_mode][GDC_VBP] << 10)
+ + (master_param[m_mode][GDC_LF])));
+ master_gdc_fifo_empty();
+ master_gdc_cmd(_GDC_PITCH);
+ master_gdc_prm(MasterPCH);
+ master_gdc_fifo_empty();
+
+ /* GDC slave */
+ gdc_cmd(_GDC_SYNC);
+ gdc_prm(0x06);
+ gdc_prm(slave_param[s_mode][GDC_CR]);
+ gdc_word_prm((slave_param[s_mode][GDC_HFP] << 10)
+ + (slave_param[s_mode][GDC_VS] << 5)
+ + (slave_param[s_mode][GDC_HS]));
+ gdc_prm(slave_param[s_mode][GDC_HBP]);
+ gdc_prm(slave_param[s_mode][GDC_VFP]);
+ gdc_word_prm((slave_param[s_mode][GDC_VBP] << 10)
+ + (slave_param[s_mode][GDC_LF]));
+ gdc_fifo_empty();
+ gdc_cmd(_GDC_PITCH);
+ gdc_prm(SlavePCH[gdc_clock]);
+ gdc_fifo_empty();
+
+ /* set Master GDC scroll param */
+ master_gdc_wait_vsync();
+ master_gdc_wait_vsync();
+ master_gdc_wait_vsync();
+ master_gdc_cmd(_GDC_SCROLL);
+ master_gdc_word_prm(0);
+ master_gdc_word_prm((master_param[m_mode][GDC_LF] << 4) | 0x0000);
+ master_gdc_fifo_empty();
+
+ /* set Slave GDC scroll param */
+ gdc_wait_vsync();
+ gdc_cmd(_GDC_SCROLL);
+ gdc_word_prm(0);
+ if (gdc_clock == _5MHZ){
+ gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
+ }else{
+ gdc_word_prm(SlaveScrlLF[mode] << 4);
+ }
+ gdc_fifo_empty();
+
+ gdc_word_prm(0);
+ if (gdc_clock == _5MHZ){
+ gdc_word_prm((SlaveScrlLF[mode] << 4) | 0x4000);
+ }else{
+ gdc_word_prm(SlaveScrlLF[mode] << 4);
+ }
+ gdc_fifo_empty();
+
+ /* sync start */
+ gdc_cmd(_GDC_STOP);
+
+ gdc_wait_vsync();
+ gdc_wait_vsync();
+ gdc_wait_vsync();
+
+ master_gdc_cmd(_GDC_START);
+}
+#endif /* 30 line */
+
#endif /* NSC */
diff --git a/sys/pc98/pc98/syscons.h b/sys/pc98/pc98/syscons.h
index a265d15277ae..3d4b8d3ed00b 100644
--- a/sys/pc98/pc98/syscons.h
+++ b/sys/pc98/pc98/syscons.h
@@ -1,18 +1,18 @@
/*-
- * Copyright (c) 1992-1998 Sen Schmidt
+ * Copyright (c) 1995 Sen Schmidt
* 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,
- * without modification, immediately at the beginning of the file.
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -25,7 +25,7 @@
* (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: syscons.h,v 1.27 1999/01/17 15:42:27 kato Exp $
+ * $Id: syscons.h,v 1.24 1998/08/03 10:50:57 kato Exp $
*/
#ifndef _PC98_PC98_SYSCONS_H_
@@ -38,13 +38,8 @@
#define pa_to_va(pa) (KERNBASE + (pa)) /* works if ISMAPPED(pa...) */
/* printable chars */
-#ifdef PC98
-#define PRINTABLE(ch) ((ch) > 0x1b || ((ch) > 0x0f && (ch) < 0x1b) \
- || (ch) < 0x07)
-#else
#define PRINTABLE(ch) ((ch) > 0x1b || ((ch) > 0x0d && (ch) < 0x1b) \
|| (ch) < 0x07)
-#endif
/* macros for "intelligent" screen update */
#define mark_for_update(scp, x) {\
@@ -57,7 +52,11 @@
}
/* status flags */
+#define LOCK_KEY_MASK 0x0000F
+#define LED_MASK 0x00007
#define UNKNOWN_MODE 0x00010
+#define KBD_RAW_MODE 0x00020
+#define KBD_CODE_MODE 0x00040
#define SWITCH_WAIT_REL 0x00080
#define SWITCH_WAIT_ACQ 0x00100
#define BUFFER_SAVED 0x00200
@@ -66,22 +65,15 @@
#define MOUSE_MOVED 0x01000
#define MOUSE_CUTTING 0x02000
#define MOUSE_VISIBLE 0x04000
-#define GRAPHICS_MODE 0x08000
-#define PIXEL_MODE 0x10000
-#define SAVER_RUNNING 0x20000
/* configuration flags */
#define VISUAL_BELL 0x00001
#define BLINK_CURSOR 0x00002
#define CHAR_CURSOR 0x00004
-/* these options are now obsolete; use corresponding options for kbd driver */
-#if 0
#define DETECT_KBD 0x00008
#define XT_KEYBD 0x00010
#define KBD_NORESET 0x00020
-#endif
#define QUIET_BELL 0x00040
-#define VESA800X600 0x00080
/* attribute flags */
#define NORMAL_ATTR 0x00
@@ -92,6 +84,9 @@
#define FOREGROUND_CHANGED 0x10
#define BACKGROUND_CHANGED 0x20
+/* video hardware memory addresses */
+#define VIDEOMEM 0x000A0000
+
/* misc defines */
#define FALSE 0
#define TRUE 1
@@ -116,11 +111,24 @@ static unsigned int BELL_PITCH = 1678;
#define FONT_14 4
#define FONT_16 8
-#ifdef PC98
/* defines related to hardware addresses */
+#ifdef PC98
#define TEXT_GDC IO_GDC1 /* 0x60 */
#define TEXT_VRAM (KERNBASE+0xA0000)
#define ATTR_OFFSET 0x1000
+#else /* IBM */
+#define MONO_BASE 0x3B4 /* crt controller base mono */
+#define COLOR_BASE 0x3D4 /* crt controller base color */
+#define MISC 0x3C2 /* misc output register */
+#define ATC IO_VGA+0x00 /* attribute controller */
+#define TSIDX IO_VGA+0x04 /* timing sequencer idx */
+#define TSREG IO_VGA+0x05 /* timing sequencer data */
+#define PIXMASK IO_VGA+0x06 /* pixel write mask */
+#define PALRADR IO_VGA+0x07 /* palette read address */
+#define PALWADR IO_VGA+0x08 /* palette write address */
+#define PALDATA IO_VGA+0x09 /* palette data register */
+#define GDCIDX IO_VGA+0x0E /* graph data controller idx */
+#define GDCREG IO_VGA+0x0F /* graph data controller data */
#endif
/* special characters */
@@ -146,8 +154,6 @@ typedef struct term_stat {
} term_stat;
typedef struct scr_stat {
- int ad; /* video adapter index */
- video_adapter_t *adp; /* video adapter structure */
u_short *scr_buf; /* buffer when off screen */
#ifdef PC98
u_short *atr_buf; /* buffer when off screen */
@@ -161,14 +167,11 @@ typedef struct scr_stat {
int ysize; /* Y text size */
int xpixel; /* X graphics size */
int ypixel; /* Y graphics size */
- int xoff; /* X offset in pixel mode */
- int yoff; /* Y offset in pixel mode */
int font_size; /* fontsize in Y direction */
int start; /* modified area start */
int end; /* modified area end */
term_stat term; /* terminal emulation stuff */
int status; /* status (bitfield) */
- int kbd_mode; /* keyboard I/O mode */
u_short *cursor_pos; /* cursor buffer position */
u_short *cursor_oldpos; /* cursor old buffer position */
#ifndef PC98
@@ -192,6 +195,7 @@ typedef struct scr_stat {
u_short bell_duration;
u_short bell_pitch;
u_char border; /* border color */
+ int initial_mode; /* initial mode */
int mode; /* mode */
pid_t pid; /* pid of controlling proc */
struct proc *proc; /* proc* of controlling proc */
@@ -208,30 +212,14 @@ typedef struct scr_stat {
#endif
int history_size; /* size of history buffer */
struct apmhook r_hook; /* reconfiguration support */
- int splash_save_mode; /* saved mode for splash screen */
- int splash_save_status; /* saved status for splash screen */
+#ifdef SC_SPLASH_SCREEN
+ u_char splash_save_mode; /* saved mode for splash screen */
+#endif
#ifdef KANJI
u_char kanji_1st_char;
-#define KTYPE_ASCII 0
-#define KTYPE_KANA 1
-#define KTYPE_JKANA 0x10
-#define KTYPE_7JIS 0x20
-#define KTYPE_SJIS 2
-#define KTYPE_UJIS 4
-#define KTYPE_SUKANA 3
-#define KTYPE_SUJIS 6
-#define KTYPE_KANIN 0x80
-#define KTYPE_ASCIN 0x40
- u_char kanji_type; /* 0: Ascii code 1: HANKAKU */
- /* 2: Shift JIS 4: UJIS */
- /* 3: Shift JIS or UJIS HANKAKU */
- /* 6: Shift JIS or UJIS */
+ u_char kanji_type; /* 0: ASCII CODE 1: HANKAKU ? */
+ /* 2: SHIFT JIS 4: EUC */
/* 0x10: JIS HANKAKU 0x20: JIS */
- /* 0x80: Kanji Invoke sequence */
- /* 0x40: Ascii Invoke sequence */
-#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee))
-#define IS_KTYPE_KANA(A) ((A) & 0x11)
-#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0)
#endif
} scr_stat;
@@ -240,56 +228,22 @@ typedef struct default_attr {
int rev_color; /* reverse hardware color */
} default_attr;
-
-#define ISTEXTSC(scp) (!((scp)->status \
- & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE)))
-#define ISGRAPHSC(scp) (((scp)->status \
- & (UNKNOWN_MODE | GRAPHICS_MODE)))
-#define ISPIXELSC(scp) (((scp)->status \
- & (UNKNOWN_MODE | GRAPHICS_MODE | PIXEL_MODE))\
- == PIXEL_MODE)
-#define ISUNKNOWNSC(scp) ((scp)->status & UNKNOWN_MODE)
-
-#define ISFONTAVAIL(af) ((af) & V_ADP_FONT)
-#define ISMOUSEAVAIL(af) ((af) & V_ADP_FONT)
-#define ISPALAVAIL(af) ((af) & V_ADP_PALETTE)
-
/* misc prototypes used by different syscons related LKM's */
+void set_border(u_char color);
+void set_mode(scr_stat *scp);
+void copy_font(int operation, int font_type, char* font_image);
+void load_palette(char *palette);
+int add_scrn_saver(void (*this)(int));
+int remove_scrn_saver(void (*this)(int));
-/* syscons.c */
-extern int (*sc_user_ioctl)(dev_t dev, u_long cmd, caddr_t data, int flag,
- struct proc *p);
-
-int set_mode(scr_stat *scp);
-scr_stat *sc_get_scr_stat(dev_t dev);
-
-void copy_font(scr_stat *scp, int operation, int font_size, u_char *font_image);
-void set_border(scr_stat *scp, int color);
-#define save_palette(adp, pal) \
- (*vidsw[(adp)->va_index]->save_palette)((adp), (pal))
-#define load_palette(adp, pal) \
- (*vidsw[(adp)->va_index]->load_palette)((adp), (pal))
-
-void sc_touch_scrn_saver(void);
-void sc_clear_screen(scr_stat *scp);
-void sc_move_mouse(scr_stat *scp, int x, int y);
-int sc_clean_up(scr_stat *scp);
-void sc_alloc_scr_buffer(scr_stat *scp, int wait, int clear);
-void sc_alloc_cut_buffer(scr_stat *scp, int wait);
-void sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait);
-struct tty *scdevtotty(dev_t dev);
-
-/* scvidctl.c */
-int sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode,
- int xsize, int ysize, int fontsize);
-int sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode);
-int sc_set_pixel_mode(scr_stat *scp, struct tty *tp,
- int xsize, int ysize, int fontsize);
-int sc_vid_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag,
- struct proc *p);
+#ifdef SC_SPLASH_SCREEN
+void splash(int);
+int splash_load(void);
+int splash_unload(void);
+#endif
#ifdef PC98
unsigned int at2pc98(unsigned int attr);
#endif
-#endif /* !_PC98_PC98_SYSCONS_H_ */
+#endif /* !_I386_ISA_SYSCONS_H_ */
diff --git a/sys/pc98/pc98/wd.c b/sys/pc98/pc98/wd.c
index eb6522bf8fb9..90fc584ca221 100644
--- a/sys/pc98/pc98/wd.c
+++ b/sys/pc98/pc98/wd.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
- * $Id: wd.c,v 1.70 1999/01/16 11:43:12 kato Exp $
+ * $Id: wd.c,v 1.63 1998/09/15 14:07:08 kato Exp $
*/
/* TODO:
@@ -67,8 +67,8 @@
#include "opt_atapi.h"
#include "opt_devfs.h"
#include "opt_hw_wdog.h"
-#include "opt_ide_delay.h"
#include "opt_wd.h"
+#include "pci.h"
#include <sys/param.h>
#include <sys/dkbad.h>
@@ -112,11 +112,7 @@
extern void wdstart(int ctrlr);
-#ifdef IDE_DELAY
-#define TIMEOUT IDE_DELAY
-#else
#define TIMEOUT 10000
-#endif
#define RETRIES 5 /* number of retries before giving up */
#define RECOVERYTIME 500000 /* usec for controller to recover after err */
#define MAXTRANSFER 255 /* max size of transfer in sectors */
@@ -337,16 +333,19 @@ wdprobe(struct isa_device *dvp)
du->dk_ctrlr = dvp->id_unit;
interface = du->dk_ctrlr / 2;
du->dk_interface = interface;
- du->dk_port = dvp->id_iobase;
- if (wddma[interface].wdd_candma != NULL) {
- du->dk_dmacookie =
- wddma[interface].wdd_candma(dvp->id_iobase, du->dk_ctrlr,
- du->dk_unit);
- du->dk_altport =
- wddma[interface].wdd_altiobase(du->dk_dmacookie);
- }
- if (du->dk_altport == 0)
+#if !defined(DISABLE_PCI_IDE) && (NPCI > 0)
+ if (wddma[interface].wdd_candma) {
+ du->dk_dmacookie = wddma[interface].wdd_candma(dvp->id_iobase, du->dk_ctrlr);
+ du->dk_port = dvp->id_iobase;
+ du->dk_altport = wddma[interface].wdd_altiobase(du->dk_dmacookie);
+ } else {
+ du->dk_port = dvp->id_iobase;
du->dk_altport = du->dk_port + wd_ctlr;
+ }
+#else
+ du->dk_port = dvp->id_iobase;
+ du->dk_altport = du->dk_port + wd_ctlr;
+#endif
/* check if we have registers that work */
#ifdef PC98
@@ -367,11 +366,9 @@ wdprobe(struct isa_device *dvp)
}
}
du->dk_altport = du->dk_port + wd_ctlr;
-#if 0
if ((PC98_SYSTEM_PARAMETER(0x55d) & 3) == 0) {
goto nodevice;
}
-#endif
outb(0x432,(du->dk_unit)%2);
#else /* IBM-PC */
outb(du->dk_port + wd_sdh, WDSD_IBM); /* set unit 0 */
@@ -395,31 +392,11 @@ wdprobe(struct isa_device *dvp)
if (inb(du->dk_port + wd_cyl_lo) == 0x14 &&
inb(du->dk_port + wd_cyl_hi) == 0xeb)
goto reset_ok;
-#ifdef PC98
- du->dk_unit = 2;
-#else
du->dk_unit = 1;
-#endif
outb(du->dk_port + wd_sdh, WDSD_IBM | 0x10); /* slave */
if (inb(du->dk_port + wd_cyl_lo) == 0x14 &&
inb(du->dk_port + wd_cyl_hi) == 0xeb)
goto reset_ok;
-#ifdef PC98
- du->dk_unit = 1;
- outb(0x432,(du->dk_unit)%2);
- if (wdreset(du) == 0)
- goto reset_ok;
- /* test for ATAPI signature */
- outb(du->dk_port + wd_sdh, WDSD_IBM); /* master */
- if (inb(du->dk_port + wd_cyl_lo) == 0x14 &&
- inb(du->dk_port + wd_cyl_hi) == 0xeb)
- goto reset_ok;
- du->dk_unit = 3;
- outb(du->dk_port + wd_sdh, WDSD_IBM | 0x10); /* slave */
- if (inb(du->dk_port + wd_cyl_lo) == 0x14 &&
- inb(du->dk_port + wd_cyl_hi) == 0xeb)
- goto reset_ok;
-#endif
#endif
DELAY(RECOVERYTIME);
if (wdreset(du) != 0) {
@@ -509,8 +486,6 @@ wdattach(struct isa_device *dvp)
struct disk *du;
struct wdparams *wp;
- dvp->id_intr = wdintr;
-
if (dvp->id_unit >= NWDC)
return (0);
@@ -773,17 +748,17 @@ wdstrategy(register struct buf *bp)
/* queue transfer on drive, activate drive and controller if idle */
s = splbio();
+ bufqdisksort(&drive_queue[lunit], bp);
+
+ if (wdutab[lunit].b_active == 0)
+ wdustart(du); /* start drive */
+
/* Pick up changes made by readdisklabel(). */
if (du->dk_flags & DKFL_LABELLING && du->dk_state > RECAL) {
wdsleep(du->dk_ctrlr, "wdlab");
du->dk_state = WANTOPEN;
}
- bufqdisksort(&drive_queue[lunit], bp);
-
- if (wdutab[lunit].b_active == 0)
- wdustart(du); /* start drive */
-
#ifdef CMD640
if (wdtab[du->dk_ctrlr_cmd640].b_active == 0)
#else
@@ -1166,12 +1141,11 @@ wdstart(int ctrlr)
*/
void
-wdintr(void *unitnum)
+wdintr(int unit)
{
register struct disk *du;
register struct buf *bp;
int dmastat = 0; /* Shut up GCC */
- int unit = (int)unitnum;
#ifdef CMD640
int ctrlr_atapi;
@@ -1223,7 +1197,8 @@ wdintr(void *unitnum)
if (du->dk_flags & (DKFL_DMA|DKFL_USEDMA)) {
/* XXX SMP boxes sometimes generate an early intr. Why? */
if ((wddma[du->dk_interface].wdd_dmastatus(du->dk_dmacookie) & WDDS_INTERRUPT)
- != 0)
+ == 0)
+ return;
dmastat = wddma[du->dk_interface].wdd_dmadone(du->dk_dmacookie);
}
@@ -2097,8 +2072,7 @@ failed:
* check drive's DMA capability
*/
if (wddma[du->dk_interface].wdd_candma) {
- du->dk_dmacookie = wddma[du->dk_interface].wdd_candma(
- du->dk_port, du->dk_ctrlr, du->dk_unit);
+ du->dk_dmacookie = wddma[du->dk_interface].wdd_candma(du->dk_port, du->dk_ctrlr);
/* does user want this? */
if ((du->cfg_flags & WDOPT_DMA) &&
/* have we got a DMA controller? */
@@ -2502,11 +2476,11 @@ static void
wderror(struct buf *bp, struct disk *du, char *mesg)
{
if (bp == NULL)
- printf("wd%d: %s", du->dk_lunit, mesg);
+ printf("wd%d: %s:\n", du->dk_lunit, mesg);
else
diskerr(bp, "wd", mesg, LOG_PRINTF, du->dk_skip,
dsgetlabel(bp->b_dev, du->dk_slices));
- printf(" (status %b error %b)\n",
+ printf("wd%d: status %b error %b\n", du->dk_lunit,
du->dk_status, WDCS_BITS, du->dk_error, WDERR_BITS);
}