diff options
author | Yoshihiro Takahashi <nyan@FreeBSD.org> | 2017-01-28 02:22:15 +0000 |
---|---|---|
committer | Yoshihiro Takahashi <nyan@FreeBSD.org> | 2017-01-28 02:22:15 +0000 |
commit | 2b375b4edd1b98884c3031d6ccd61acb10bd895d (patch) | |
tree | f35e4f57ad890ac86d5cb5d3ef760344a41fc0e6 /sys/pc98/cbus | |
parent | 34bac11eba2841255bf6319ec78728f0f941c6ac (diff) | |
download | src-2b375b4edd1b98884c3031d6ccd61acb10bd895d.tar.gz src-2b375b4edd1b98884c3031d6ccd61acb10bd895d.zip |
Notes
Diffstat (limited to 'sys/pc98/cbus')
-rw-r--r-- | sys/pc98/cbus/30line.h | 130 | ||||
-rw-r--r-- | sys/pc98/cbus/cbus.h | 63 | ||||
-rw-r--r-- | sys/pc98/cbus/cbus_dma.c | 534 | ||||
-rw-r--r-- | sys/pc98/cbus/cbus_dmareg.h | 44 | ||||
-rw-r--r-- | sys/pc98/cbus/gdc.c | 1487 | ||||
-rw-r--r-- | sys/pc98/cbus/nmi.c | 69 | ||||
-rw-r--r-- | sys/pc98/cbus/olpt.c | 648 | ||||
-rw-r--r-- | sys/pc98/cbus/olptreg.h | 48 | ||||
-rw-r--r-- | sys/pc98/cbus/pckbd.c | 999 | ||||
-rw-r--r-- | sys/pc98/cbus/pckbdtables.h | 203 | ||||
-rw-r--r-- | sys/pc98/cbus/pcrtc.c | 249 | ||||
-rw-r--r-- | sys/pc98/cbus/pmc.c | 244 | ||||
-rw-r--r-- | sys/pc98/cbus/sc_machdep.h | 52 | ||||
-rw-r--r-- | sys/pc98/cbus/scgdcrndr.c | 208 | ||||
-rw-r--r-- | sys/pc98/cbus/scterm-sck.c | 1229 | ||||
-rw-r--r-- | sys/pc98/cbus/sctermvar.h | 432 | ||||
-rw-r--r-- | sys/pc98/cbus/scvtb.c | 399 | ||||
-rw-r--r-- | sys/pc98/cbus/sio.c | 4387 | ||||
-rw-r--r-- | sys/pc98/cbus/sio_cbus.c | 119 | ||||
-rw-r--r-- | sys/pc98/cbus/syscons_cbus.c | 202 |
20 files changed, 0 insertions, 11746 deletions
diff --git a/sys/pc98/cbus/30line.h b/sys/pc98/cbus/30line.h deleted file mode 100644 index c2e0f107a260..000000000000 --- a/sys/pc98/cbus/30line.h +++ /dev/null @@ -1,130 +0,0 @@ -/*- - * Copyright (c) 1994, 1995, 1996. FreeBSD(98) porting 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. - * - * $FreeBSD$ - */ - -#ifndef __PC98_PC98_30LINE_H__ -#define __PC98_PC98_30LINE_H__ - -#define LINE30_ROW 30 -#define _HS 1 + 1 -#define _VS 2 -#define _HFP 3 + 1 -#define _HBP 14 + 1 -#define _VFP 11 -#define _VBP 44 - -#define _CR 80 -#define _LF LINE30_ROW*16 - -#define _GDC_RESET 0x00 -#define _GDC_SYNC 0x0e -#define _GDC_MASTER 0x6f -#define _GDC_SLAVE 0x6e -#define _GDC_START 0x0d -#define _GDC_STOP 0x0c -#define _GDC_SCROLL 0x70 -#define _GDC_PITCH 0x47 - -#define GDC_CR 0 -#define GDC_VS 1 -#define GDC_HS 2 -#define GDC_HFP 3 -#define GDC_HBP 4 -#define GDC_VFP 5 -#define GDC_VBP 6 -#define GDC_LF 7 - - -#define _24KHZ 0 -#define _31KHZ 1 - -#define _2_5MHZ 0 -#define _5MHZ 1 - -#define _25L 0 -#define _30L 1 - -#define T25_G400 0 -#define T30_G400 1 -#define T30_G480 2 - -static void master_gdc_cmd(unsigned int); -static void master_gdc_prm(unsigned int); -static void master_gdc_word_prm(unsigned int); -#ifdef LINE30 -static void master_gdc_fifo_empty(void); -#endif -static void master_gdc_wait_vsync(void); - -static void gdc_cmd(unsigned int); -#ifdef LINE30 -static void gdc_prm(unsigned int); -static void gdc_word_prm(unsigned int); -static void gdc_fifo_empty(void); -#endif -static void gdc_wait_vsync(void); - -#ifdef LINE30 -static int check_gdc_clock(void); - -static int gdc_INFO = _25L; -#endif -static int gdc_FH = _24KHZ; -static void initialize_gdc(unsigned int, int); - -#ifdef LINE30 -static unsigned int master_param[2][2][8] = { -{{78, 8, 7, 9, 7, 7, 25, 400}, /* 400/24k */ - {_CR-2, _VS, _HS-1, _HFP-1, _HBP-1, _VFP, _VBP, _LF}}, /* 480/24k */ -{{78, 2, 7, 3, 7, 13, 34, 400}, /* 400/31k */ - {78, 2, 11, 3, 3, 6, 37, 480}}}; /* 480/31k */ - -static unsigned int slave_param[2][6][8] = { -{{38, 8, 3, 4, 3, 7, 25, 400}, /* normal */ - {78, 8, 7, 9, 7, 7, 25, 400}, - {_CR/2-2, _VS, (_HS)/2-1, (_HFP)/2-1, (_HBP)/2-1, - _VFP+(_LF-400)/2+8, _VBP+(_LF-400)/2-8, 400}, /* 30 & 400 */ - {_CR-2, _VS, _HS-1, _HFP-1, _HBP-1, - _VFP+(_LF-400)/2+8, _VBP+(_LF-400)/2-8, 400}, - {_CR/2-2, _VS, (_HS)/2-1, (_HFP)/2-1, (_HBP)/2-1, - _VFP, _VBP, _LF}, /* 30 & 480 */ - {_CR-2, _VS, _HS-1, _HFP-1, _HBP-1, _VFP, _VBP, _LF}}, -{{38, 2, 3, 1, 3, 13, 34, 400}, /* normal */ - {78, 2, 7, 3, 7, 13, 34, 400}, - {38, 2, 5, 1, 1, 6+48, 37+32, 400}, /* 30 & 400 */ - {78, 2, 11, 3, 3, 6+48, 37+32, 400}, - {38, 2, 5, 1, 1, 6, 37, 480}, /* 30 & 480 */ - {78, 2, 11, 3, 3, 6, 37, 480}}}; - -static int SlavePCH[2] = {40,80}; -static int MasterPCH = 80; -static int SlaveScrlLF[3] = {400,400,_LF}; -#endif - -#endif /* __PC98_PC98_30LINE_H__ */ diff --git a/sys/pc98/cbus/cbus.h b/sys/pc98/cbus/cbus.h deleted file mode 100644 index 302245f896f6..000000000000 --- a/sys/pc98/cbus/cbus.h +++ /dev/null @@ -1,63 +0,0 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * 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. - * 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: @(#)isa.h 5.7 (Berkeley) 5/9/91 - * $FreeBSD$ - */ - -#ifndef _PC98_PC98_PC98_H_ -#define _PC98_PC98_PC98_H_ - -/* - * PC98 Bus conventions - * modified for PC9801 by A.Kojima F.Ukai M.Ishii - * Kyoto University Microcomputer Club (KMC) - */ - -/* - * Input / Output Port Assignments -- PC98 IO address ... very dirty (^_^; - */ - -#define IO_ICU1 0x000 /* 8259A Interrupt Controller #1 */ -#define IO_ICU2 0x008 /* 8259A Interrupt Controller #2 */ -#define IO_RTC 0x020 /* 4990A RTC */ -#define IO_SYSPORT 0x031 /* 8255A System Port */ -#define IO_KBD 0x041 /* 8251A Keyboard */ -#define IO_COM2 0x0B1 /* 8251A RS232C serial I/O (ext) */ -#define IO_COM3 0x0B9 /* 8251A RS232C serial I/O (ext) */ -#define IO_FDPORT 0x0BE /* FD I/F port (1M<->640K,EMTON) */ - -/* - * Input / Output Port Sizes - */ -#define IO_KBDSIZE 16 /* 8042 Keyboard controllers */ - -#endif /* !_PC98_PC98_PC98_H_ */ diff --git a/sys/pc98/cbus/cbus_dma.c b/sys/pc98/cbus/cbus_dma.c deleted file mode 100644 index 02d9d0c67ae3..000000000000 --- a/sys/pc98/cbus/cbus_dma.c +++ /dev/null @@ -1,534 +0,0 @@ -/*- - * Copyright (c) 1991 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * 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. - * 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: @(#)isa.c 7.2 (Berkeley) 5/13/91 - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -/* - * code to manage AT bus - * - * 92/08/18 Frank P. MacLachlan (fpm@crash.cts.com): - * Fixed uninitialized variable problem and added code to deal - * with DMA page boundaries in isa_dmarangecheck(). Fixed word - * mode DMA count compution and reorganized DMA setup code in - * isa_dmastart() - */ - -#include "opt_pc98.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/lock.h> -#include <sys/proc.h> -#include <sys/mutex.h> -#include <sys/module.h> -#include <machine/md_var.h> -#include <vm/vm.h> -#include <vm/vm_param.h> -#include <vm/pmap.h> -#include <isa/isavar.h> -#include <pc98/cbus/cbus.h> -#include <pc98/cbus/cbus_dmareg.h> - -static int isa_dmarangecheck(caddr_t va, u_int length, int chan); - -static caddr_t dma_bouncebuf[4]; -static u_int dma_bouncebufsize[4]; -static u_int8_t dma_bounced = 0; -static u_int8_t dma_busy = 0; /* Used in isa_dmastart() */ -static u_int8_t dma_inuse = 0; /* User for acquire/release */ -static u_int8_t dma_auto_mode = 0; -static struct mtx isa_dma_lock; -MTX_SYSINIT(isa_dma_lock, &isa_dma_lock, "isa DMA lock", MTX_DEF); - -#define VALID_DMA_MASK (3) - -/* high byte of address is stored in this port for i-th dma channel */ -static int dmapageport[4] = { 0x27, 0x21, 0x23, 0x25 }; - -/* - * Setup a DMA channel's bounce buffer. - */ -int -isa_dma_init(int chan, u_int bouncebufsize, int flag) -{ - void *buf; - -#ifdef DIAGNOSTIC - if (chan & ~VALID_DMA_MASK) - panic("isa_dma_init: channel out of range"); - if (dma_bouncebuf[chan] != NULL) - panic("isa_dma_init: impossible request"); -#endif - - - /* Try malloc() first. It works better if it works. */ - buf = malloc(bouncebufsize, M_DEVBUF, flag); - if (buf != NULL) { - if (isa_dmarangecheck(buf, bouncebufsize, chan) != 0) { - free(buf, M_DEVBUF); - buf = NULL; - } - } - - if (buf == NULL) { - buf = contigmalloc(bouncebufsize, M_DEVBUF, flag, 0ul, 0xfffffful, - 1ul, chan & 4 ? 0x20000ul : 0x10000ul); - } - - if (buf == NULL) - return (ENOMEM); - - mtx_lock(&isa_dma_lock); - - dma_bouncebufsize[chan] = bouncebufsize; - dma_bouncebuf[chan] = buf; - - mtx_unlock(&isa_dma_lock); - - return (0); -} - -/* - * Register a DMA channel's usage. Usually called from a device driver - * in open() or during its initialization. - */ -int -isa_dma_acquire(chan) - int chan; -{ -#ifdef DIAGNOSTIC - if (chan & ~VALID_DMA_MASK) - panic("isa_dma_acquire: channel out of range"); -#endif - - mtx_lock(&isa_dma_lock); - if (dma_inuse & (1 << chan)) { - printf("isa_dma_acquire: channel %d already in use\n", chan); - mtx_unlock(&isa_dma_lock); - return (EBUSY); - } - dma_inuse |= (1 << chan); - dma_auto_mode &= ~(1 << chan); - mtx_unlock(&isa_dma_lock); - - return (0); -} - -/* - * Unregister a DMA channel's usage. Usually called from a device driver - * during close() or during its shutdown. - */ -void -isa_dma_release(chan) - int chan; -{ -#ifdef DIAGNOSTIC - if (chan & ~VALID_DMA_MASK) - panic("isa_dma_release: channel out of range"); - - mtx_lock(&isa_dma_lock); - if ((dma_inuse & (1 << chan)) == 0) - printf("isa_dma_release: channel %d not in use\n", chan); -#else - mtx_lock(&isa_dma_lock); -#endif - - if (dma_busy & (1 << chan)) { - dma_busy &= ~(1 << chan); - /* - * XXX We should also do "dma_bounced &= (1 << chan);" - * because we are acting on behalf of isa_dmadone() which - * was not called to end the last DMA operation. This does - * not matter now, but it may in the future. - */ - } - - dma_inuse &= ~(1 << chan); - dma_auto_mode &= ~(1 << chan); - - mtx_unlock(&isa_dma_lock); -} - -/* - * isa_dmastart(): program 8237 DMA controller channel, avoid page alignment - * problems by using a bounce buffer. - */ -void -isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan) -{ - vm_paddr_t phys; - int waport; - caddr_t newaddr; - int dma_range_checked; - - /* translate to physical */ - phys = pmap_extract(kernel_pmap, (vm_offset_t)addr); - dma_range_checked = isa_dmarangecheck(addr, nbytes, chan); - -#ifdef DIAGNOSTIC - if (chan & ~VALID_DMA_MASK) - panic("isa_dmastart: channel out of range"); - - if ((chan < 4 && nbytes > (1<<16)) - || (chan >= 4 && (nbytes > (1<<17) || (u_int)addr & 1))) - panic("isa_dmastart: impossible request"); - - mtx_lock(&isa_dma_lock); - if ((dma_inuse & (1 << chan)) == 0) - printf("isa_dmastart: channel %d not acquired\n", chan); -#else - mtx_lock(&isa_dma_lock); -#endif - -#if 0 - /* - * XXX This should be checked, but drivers like ad1848 only call - * isa_dmastart() once because they use Auto DMA mode. If we - * leave this in, drivers that do this will print this continuously. - */ - if (dma_busy & (1 << chan)) - printf("isa_dmastart: channel %d busy\n", chan); -#endif - - dma_busy |= (1 << chan); - - if (dma_range_checked) { - if (dma_bouncebuf[chan] == NULL - || dma_bouncebufsize[chan] < nbytes) - panic("isa_dmastart: bad bounce buffer"); - dma_bounced |= (1 << chan); - newaddr = dma_bouncebuf[chan]; - - /* copy bounce buffer on write */ - if (!(flags & ISADMA_READ)) - bcopy(addr, newaddr, nbytes); - addr = newaddr; - } - - if (flags & ISADMA_RAW) { - dma_auto_mode |= (1 << chan); - } else { - dma_auto_mode &= ~(1 << chan); - } - - if (need_pre_dma_flush) - wbinvd(); /* wbinvd (WB cache flush) */ - - /* set dma channel mode, and reset address ff */ - - /* If ISADMA_RAW flag is set, then use autoinitialise mode */ - if (flags & ISADMA_RAW) { - if (flags & ISADMA_READ) - outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_WRITE|chan); - else - outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_READ|chan); - } else { - if (flags & ISADMA_READ) - outb(DMA1_MODE, DMA37MD_SINGLE|DMA37MD_WRITE|chan); - else - outb(DMA1_MODE, DMA37MD_SINGLE|DMA37MD_READ|chan); - } - outb(DMA1_FFC, 0); - - /* send start address */ - waport = DMA1_CHN(chan); - outb(waport, phys); - outb(waport, phys>>8); - outb(dmapageport[chan], phys>>16); - - /* send count */ - outb(waport + 2, --nbytes); - outb(waport + 2, nbytes>>8); - - /* unmask channel */ - outb(DMA1_SMSK, chan); - - mtx_unlock(&isa_dma_lock); -} - -void -isa_dmadone(int flags, caddr_t addr, int nbytes, int chan) -{ - - if (flags & ISADMA_READ) { - /* cache flush only after reading 92/12/9 by A.Kojima */ - if (need_post_dma_flush) - invd(); - } - -#ifdef DIAGNOSTIC - if (chan & ~VALID_DMA_MASK) - panic("isa_dmadone: channel out of range"); - - if ((dma_inuse & (1 << chan)) == 0) - printf("isa_dmadone: channel %d not acquired\n", chan); -#endif - - mtx_lock(&isa_dma_lock); - if (((dma_busy & (1 << chan)) == 0) && - (dma_auto_mode & (1 << chan)) == 0 ) - printf("isa_dmadone: channel %d not busy\n", chan); - - if ((dma_auto_mode & (1 << chan)) == 0) - outb(DMA1_SMSK, (chan & 3) | 4); - - if (dma_bounced & (1 << chan)) { - /* copy bounce buffer on read */ - if (flags & ISADMA_READ) - bcopy(dma_bouncebuf[chan], addr, nbytes); - - dma_bounced &= ~(1 << chan); - } - dma_busy &= ~(1 << chan); - mtx_unlock(&isa_dma_lock); -} - -/* - * Check for problems with the address range of a DMA transfer - * (non-contiguous physical pages, outside of bus address space, - * crossing DMA page boundaries). - * Return true if special handling needed. - */ - -static int -isa_dmarangecheck(caddr_t va, u_int length, int chan) -{ - vm_paddr_t phys, priorpage = 0; - vm_offset_t endva; - u_int dma_pgmsk = (chan & 4) ? ~(128*1024-1) : ~(64*1024-1); - - endva = (vm_offset_t)round_page((vm_offset_t)va + length); - for (; va < (caddr_t) endva ; va += PAGE_SIZE) { - phys = trunc_page(pmap_extract(kernel_pmap, (vm_offset_t)va)); -#ifdef EPSON_BOUNCEDMA -#define ISARAM_END 0x0f00000 -#else -#define ISARAM_END 0x1000000 -#endif - if (phys == 0) - panic("isa_dmacheck: no physical page present"); - if (phys >= ISARAM_END) - return (1); - if (priorpage) { - if (priorpage + PAGE_SIZE != phys) - return (1); - /* check if crossing a DMA page boundary */ - if (((u_int)priorpage ^ (u_int)phys) & dma_pgmsk) - return (1); - } - priorpage = phys; - } - return (0); -} - -/* - * Query the progress of a transfer on a DMA channel. - * - * To avoid having to interrupt a transfer in progress, we sample - * each of the high and low databytes twice, and apply the following - * logic to determine the correct count. - * - * Reads are performed with interrupts disabled, thus it is to be - * expected that the time between reads is very small. At most - * one rollover in the low count byte can be expected within the - * four reads that are performed. - * - * There are three gaps in which a rollover can occur : - * - * - read low1 - * gap1 - * - read high1 - * gap2 - * - read low2 - * gap3 - * - read high2 - * - * If a rollover occurs in gap1 or gap2, the low2 value will be - * greater than the low1 value. In this case, low2 and high2 are a - * corresponding pair. - * - * In any other case, low1 and high1 can be considered to be correct. - * - * The function returns the number of bytes remaining in the transfer, - * or -1 if the channel requested is not active. - * - */ -static int -isa_dmastatus_locked(int chan) -{ - u_long cnt = 0; - int ffport, waport; - u_long low1, high1, low2, high2; - - mtx_assert(&isa_dma_lock, MA_OWNED); - - /* channel active? */ - if ((dma_inuse & (1 << chan)) == 0) { - printf("isa_dmastatus: channel %d not active\n", chan); - return(-1); - } - /* channel busy? */ - - if (((dma_busy & (1 << chan)) == 0) && - (dma_auto_mode & (1 << chan)) == 0 ) { - printf("chan %d not busy\n", chan); - return -2 ; - } - ffport = DMA1_FFC; - waport = DMA1_CHN(chan) + 2; - - disable_intr(); /* no interrupts Mr Jones! */ - outb(ffport, 0); /* clear register LSB flipflop */ - low1 = inb(waport); - high1 = inb(waport); - outb(ffport, 0); /* clear again */ - low2 = inb(waport); - high2 = inb(waport); - enable_intr(); /* enable interrupts again */ - - /* - * Now decide if a wrap has tried to skew our results. - * Note that after TC, the count will read 0xffff, while we want - * to return zero, so we add and then mask to compensate. - */ - if (low1 >= low2) { - cnt = (low1 + (high1 << 8) + 1) & 0xffff; - } else { - cnt = (low2 + (high2 << 8) + 1) & 0xffff; - } - - if (chan >= 4) /* high channels move words */ - cnt *= 2; - return(cnt); -} - -int -isa_dmastatus(int chan) -{ - int status; - - mtx_lock(&isa_dma_lock); - status = isa_dmastatus_locked(chan); - mtx_unlock(&isa_dma_lock); - - return (status); -} - -/* - * Reached terminal count yet ? - */ -int -isa_dmatc(int chan) -{ - - return(inb(DMA1_STATUS) & (1 << chan)); -} - -/* - * Stop a DMA transfer currently in progress. - */ -int -isa_dmastop(int chan) -{ - int status; - - mtx_lock(&isa_dma_lock); - if ((dma_inuse & (1 << chan)) == 0) - printf("isa_dmastop: channel %d not acquired\n", chan); - - if (((dma_busy & (1 << chan)) == 0) && - ((dma_auto_mode & (1 << chan)) == 0)) { - printf("chan %d not busy\n", chan); - mtx_unlock(&isa_dma_lock); - return -2 ; - } - - if ((chan & 4) == 0) - outb(DMA1_SMSK, (chan & 3) | 4 /* disable mask */); - - status = isa_dmastatus_locked(chan); - - mtx_unlock(&isa_dma_lock); - - return (status); -} - -/* - * Attach to the ISA PnP descriptor for the AT DMA controller - */ -static struct isa_pnp_id atdma_ids[] = { - { 0x0002d041 /* PNP0200 */, "AT DMA controller" }, - { 0 } -}; - -static int -atdma_probe(device_t dev) -{ - int result; - - if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, atdma_ids)) <= 0) - device_quiet(dev); - return(result); -} - -static int -atdma_attach(device_t dev) -{ - return(0); -} - -static device_method_t atdma_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, atdma_probe), - DEVMETHOD(device_attach, atdma_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - { 0, 0 } -}; - -static driver_t atdma_driver = { - "atdma", - atdma_methods, - 1, /* no softc */ -}; - -static devclass_t atdma_devclass; - -DRIVER_MODULE(atdma, isa, atdma_driver, atdma_devclass, 0, 0); diff --git a/sys/pc98/cbus/cbus_dmareg.h b/sys/pc98/cbus/cbus_dmareg.h deleted file mode 100644 index 9401b916560e..000000000000 --- a/sys/pc98/cbus/cbus_dmareg.h +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright (C) 2005 TAKAHASHI Yoshihiro. 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. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#ifndef _PC98_CBUS_CBUS_DMAREG_H_ -#define _PC98_CBUS_CBUS_DMAREG_H_ - -#include <dev/ic/i8237.h> - -#define IO_DMA 0x01 /* 8237A DMA Controller */ - -/* - * Register definitions for DMA controller 1 (channels 0..3): - */ -#define DMA1_CHN(c) (IO_DMA + (4*(c))) /* addr reg for channel c */ -#define DMA1_STATUS (IO_DMA + 0x10) /* status register */ -#define DMA1_SMSK (IO_DMA + 0x14) /* single mask register */ -#define DMA1_MODE (IO_DMA + 0x16) /* mode register */ -#define DMA1_FFC (IO_DMA + 0x18) /* clear first/last FF */ - -#endif /* _PC98_CBUS_CBUS_DMAREG_H_ */ diff --git a/sys/pc98/cbus/gdc.c b/sys/pc98/cbus/gdc.c deleted file mode 100644 index 4fff4cebaf07..000000000000 --- a/sys/pc98/cbus/gdc.c +++ /dev/null @@ -1,1487 +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. - * - * $FreeBSD$ - */ - -#include "opt_gdc.h" -#include "opt_fb.h" -#include "opt_syscons.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/conf.h> -#include <sys/bus.h> -#include <machine/bus.h> -#include <sys/rman.h> -#include <machine/resource.h> - -#include <sys/fbio.h> -#include <sys/fcntl.h> - -#include <vm/vm.h> -#include <vm/pmap.h> -#include <vm/vm_param.h> - -#include <machine/md_var.h> -#include <machine/pc/bios.h> - -#include <dev/fb/fbreg.h> - -#ifdef LINE30 -#include <pc98/cbus/cbus.h> -#endif -#include <pc98/pc98/pc98_machdep.h> -#include <isa/isavar.h> - -#define TEXT_GDC 0x60 -#define GRAPHIC_GDC 0xa0 -#define ROW 25 -#define COL 80 - -#define DRIVER_NAME "gdc" - -/* cdev driver declaration */ - -#define GDC_UNIT(dev) dev2unit(dev) -#define GDC_MKMINOR(unit) (unit) - -typedef struct gdc_softc { - video_adapter_t *adp; - struct resource *res_tgdc, *res_ggdc; - struct resource *res_egc, *res_pegc, *res_grcg, *res_kcg; - struct resource *res_tmem, *res_gmem1, *res_gmem2; -#ifdef FB_INSTALL_CDEV - genfb_softc_t gensc; -#endif -} gdc_softc_t; - -#define GDC_SOFTC(unit) \ - ((gdc_softc_t *)devclass_get_softc(gdc_devclass, unit)) - -static bus_addr_t gdc_iat[] = {0, 2, 4, 6, 8, 10, 12, 14}; - -static devclass_t gdc_devclass; - -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); -static int gdc_alloc_resource(device_t dev); -static int gdc_release_resource(device_t dev); - -#ifdef FB_INSTALL_CDEV - -static d_open_t gdcopen; -static d_close_t gdcclose; -static d_read_t gdcread; -static d_write_t gdcwrite; -static d_ioctl_t gdcioctl; -static d_mmap_t gdcmmap; - -static struct cdevsw gdc_cdevsw = { - .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, - .d_open = gdcopen, - .d_close = gdcclose, - .d_read = gdcread, - .d_write = gdcwrite, - .d_ioctl = gdcioctl, - .d_mmap = gdcmmap, - .d_name = DRIVER_NAME, -}; - -#endif /* FB_INSTALL_CDEV */ - -static void -gdc_identify(driver_t *driver, device_t parent) -{ - BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, DRIVER_NAME, 0); -} - -static int -gdcprobe(device_t dev) -{ - int error; - - /* Check isapnp ids */ - if (isa_get_vendorid(dev)) - return (ENXIO); - - device_set_desc(dev, "Generic GDC"); - - error = gdc_alloc_resource(dev); - if (error) - return (error); - - error = gdc_probe_unit(device_get_unit(dev), - device_get_softc(dev), - device_get_flags(dev)); - - gdc_release_resource(dev); - - return (error); -} - -static int -gdc_attach(device_t dev) -{ - gdc_softc_t *sc; - int error; - - error = gdc_alloc_resource(dev); - if (error) - return (error); - - sc = device_get_softc(dev); - error = gdc_attach_unit(device_get_unit(dev), - sc, - device_get_flags(dev)); - if (error) { - gdc_release_resource(dev); - return error; - } - -#ifdef FB_INSTALL_CDEV - /* attach a virtual frame buffer device */ - error = fb_attach(GDC_MKMINOR(device_get_unit(dev)), - sc->adp, &gdc_cdevsw); - if (error) { - gdc_release_resource(dev); - return error; - } -#endif /* FB_INSTALL_CDEV */ - - if (bootverbose) - vidd_diag(sc->adp, bootverbose); - - return 0; -} - -static int -gdc_probe_unit(int unit, gdc_softc_t *sc, int flags) -{ - video_switch_t *sw; - - sw = vid_get_switch(DRIVER_NAME); - if (sw == NULL) - return ENXIO; - 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; - - sw = vid_get_switch(DRIVER_NAME); - if (sw == NULL) - return ENXIO; - return (*sw->init)(unit, sc->adp, flags); -} - - -static int -gdc_alloc_resource(device_t dev) -{ - int rid; - gdc_softc_t *sc; - - sc = device_get_softc(dev); - - /* TEXT GDC */ - rid = 0; - bus_set_resource(dev, SYS_RES_IOPORT, rid, TEXT_GDC, 1); - sc->res_tgdc = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, - gdc_iat, 8, RF_ACTIVE); - if (sc->res_tgdc == NULL) { - gdc_release_resource(dev); - return (ENXIO); - } - isa_load_resourcev(sc->res_tgdc, gdc_iat, 8); - - /* GRAPHIC GDC */ - rid = 8; - bus_set_resource(dev, SYS_RES_IOPORT, rid, GRAPHIC_GDC, 1); - sc->res_ggdc = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, - gdc_iat, 8, RF_ACTIVE); - if (sc->res_ggdc == NULL) { - gdc_release_resource(dev); - return (ENXIO); - } - isa_load_resourcev(sc->res_ggdc, gdc_iat, 8); - - /* EGC */ - rid = 16; - bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x4a0, 1); - sc->res_egc = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, - gdc_iat, 8, RF_ACTIVE); - if (sc->res_egc == NULL) { - gdc_release_resource(dev); - return (ENXIO); - } - isa_load_resourcev(sc->res_egc, gdc_iat, 8); - - /* PEGC */ - rid = 24; - bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x9a0, 1); - sc->res_pegc = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, - gdc_iat, 8, RF_ACTIVE); - if (sc->res_pegc == NULL) { - gdc_release_resource(dev); - return (ENXIO); - } - isa_load_resourcev(sc->res_pegc, gdc_iat, 8); - - /* CRTC/GRCG */ - rid = 32; - bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x70, 1); - sc->res_grcg = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, - gdc_iat, 8, RF_ACTIVE); - if (sc->res_grcg == NULL) { - gdc_release_resource(dev); - return (ENXIO); - } - isa_load_resourcev(sc->res_grcg, gdc_iat, 8); - - /* KCG */ - rid = 40; - bus_set_resource(dev, SYS_RES_IOPORT, rid, 0xa1, 1); - sc->res_kcg = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, - gdc_iat, 8, RF_ACTIVE); - if (sc->res_kcg == NULL) { - gdc_release_resource(dev); - return (ENXIO); - } - isa_load_resourcev(sc->res_kcg, gdc_iat, 8); - - - /* TEXT Memory */ - rid = 0; - sc->res_tmem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, - 0xa0000, 0xa4fff, 0x5000, RF_ACTIVE); - if (sc->res_tmem == NULL) { - gdc_release_resource(dev); - return (ENXIO); - } - - /* GRAPHIC Memory */ - rid = 1; - sc->res_gmem1 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, - 0xa8000, 0xbffff, 0x18000, - RF_ACTIVE); - if (sc->res_gmem1 == NULL) { - gdc_release_resource(dev); - return (ENXIO); - } - rid = 2; - sc->res_gmem2 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, - 0xe0000, 0xe7fff, 0x8000, - RF_ACTIVE); - if (sc->res_gmem2 == NULL) { - gdc_release_resource(dev); - return (ENXIO); - } - - return (0); -} - -static int -gdc_release_resource(device_t dev) -{ - gdc_softc_t *sc; - - sc = device_get_softc(dev); - - if (sc->res_tgdc) - bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->res_tgdc); - if (sc->res_ggdc) - bus_release_resource(dev, SYS_RES_IOPORT, 8, sc->res_ggdc); - if (sc->res_egc) - bus_release_resource(dev, SYS_RES_IOPORT, 16, sc->res_egc); - if (sc->res_pegc) - bus_release_resource(dev, SYS_RES_IOPORT, 24, sc->res_pegc); - if (sc->res_grcg) - bus_release_resource(dev, SYS_RES_IOPORT, 32, sc->res_grcg); - if (sc->res_kcg) - bus_release_resource(dev, SYS_RES_IOPORT, 40, sc->res_kcg); - - if (sc->res_tmem) - bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->res_tmem); - if (sc->res_gmem1) - bus_release_resource(dev, SYS_RES_MEMORY, 1, sc->res_gmem1); - if (sc->res_gmem2) - bus_release_resource(dev, SYS_RES_MEMORY, 2, sc->res_gmem2); - - return (0); -} - -/* cdev driver functions */ - -#ifdef FB_INSTALL_CDEV - -static int -gdcopen(struct cdev *dev, int flag, int mode, struct thread *td) -{ - gdc_softc_t *sc; - - sc = GDC_SOFTC(GDC_UNIT(dev)); - if (sc == NULL) - return ENXIO; - if (mode & (O_CREAT | O_APPEND | O_TRUNC)) - return ENODEV; - - return genfbopen(&sc->gensc, sc->adp, flag, mode, td); -} - -static int -gdcclose(struct cdev *dev, int flag, int mode, struct thread *td) -{ - gdc_softc_t *sc; - - sc = GDC_SOFTC(GDC_UNIT(dev)); - return genfbclose(&sc->gensc, sc->adp, flag, mode, td); -} - -static int -gdcread(struct cdev *dev, struct uio *uio, int flag) -{ - gdc_softc_t *sc; - - sc = GDC_SOFTC(GDC_UNIT(dev)); - return genfbread(&sc->gensc, sc->adp, uio, flag); -} - -static int -gdcwrite(struct cdev *dev, struct uio *uio, int flag) -{ - gdc_softc_t *sc; - - sc = GDC_SOFTC(GDC_UNIT(dev)); - return genfbread(&sc->gensc, sc->adp, uio, flag); -} - -static int -gdcioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) -{ - gdc_softc_t *sc; - - sc = GDC_SOFTC(GDC_UNIT(dev)); - return genfbioctl(&sc->gensc, sc->adp, cmd, arg, flag, td); -} - -static int -gdcmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, - int prot, vm_memattr_t *memattr) -{ - gdc_softc_t *sc; - - sc = GDC_SOFTC(GDC_UNIT(dev)); - return genfbmmap(&sc->gensc, sc->adp, offset, paddr, prot, memattr); -} - -#endif /* FB_INSTALL_CDEV */ - -static device_method_t gdc_methods[] = { - DEVMETHOD(device_identify, gdc_identify), - DEVMETHOD(device_probe, gdcprobe), - DEVMETHOD(device_attach, gdc_attach), - { 0, 0 } -}; - -static driver_t gdcdriver = { - DRIVER_NAME, - gdc_methods, - sizeof(gdc_softc_t), -}; - -DRIVER_MODULE(gdc, isa, gdcdriver, gdc_devclass, 0, 0); - -/* LOW-LEVEL */ - - -#include <pc98/cbus/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, - TEXT_GDC, 16, TEXT_GDC, /* va_io*, XXX */ - VIDEO_BUF_BASE, VIDEO_BUF_SIZE, /* va_mem* */ - TEXT_BUF_BASE, TEXT_BUF_SIZE, TEXT_BUF_SIZE, 0, /* va_window* */ - 0, 0, /* va_buffer, va_buffer_size */ - 0, M_PC98_80x25, 0, /* va_*mode* */ - }, -}; - -static video_adapter_t biosadapter[1]; - -/* video driver declarations */ -static int gdc_configure(int flags); -static int gdc_err(video_adapter_t *adp, ...); -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_blank_display_t gdc_blank_display; -static vi_mmap_t gdc_mmap_buf; -static vi_ioctl_t gdc_dev_ioctl; -static vi_clear_t gdc_clear; -static vi_fill_rect_t gdc_fill_rect; -static vi_bitblt_t gdc_bitblt; -static vi_diag_t gdc_diag; -static vi_save_palette_t gdc_save_palette; -static vi_load_palette_t gdc_load_palette; -static vi_set_win_org_t gdc_set_origin; - -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, - gdc_save_palette, - gdc_load_palette, - gdc_set_border, - gdc_save_state, - gdc_load_state, - gdc_set_origin, - gdc_read_hw_cursor, - gdc_set_hw_cursor, - gdc_set_hw_cursor_shape, - gdc_blank_display, - gdc_mmap_buf, - gdc_dev_ioctl, - gdc_clear, - gdc_fill_rect, - gdc_bitblt, - (int (*)(void))gdc_err, - (int (*)(void))gdc_err, - 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, V_INFO_MM_TEXT }, -#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, V_INFO_MM_TEXT }, -#endif -#ifndef GDC_NOGRAPHICS - { M_PC98_EGC640x400, V_INFO_COLOR | V_INFO_GRAPHICS, - 640, 400, 8, 16, 4, 4, - GRAPHICS_BUF_BASE, GRAPHICS_BUF_SIZE, GRAPHICS_BUF_SIZE, 0, 0, - V_INFO_MM_PLANAR }, - { M_PC98_PEGC640x400, V_INFO_COLOR | V_INFO_GRAPHICS | V_INFO_VESA, - 640, 400, 8, 16, 8, 1, - GRAPHICS_BUF_BASE, 0x00008000, 0x00008000, 0, 0, - V_INFO_MM_PACKED, 1 }, -#ifdef LINE30 - { M_PC98_PEGC640x480, V_INFO_COLOR | V_INFO_GRAPHICS | V_INFO_VESA, - 640, 480, 8, 16, 8, 1, - GRAPHICS_BUF_BASE, 0x00008000, 0x00008000, 0, 0, - V_INFO_MM_PACKED, 1 }, -#endif -#endif - { EOT }, -}; - -static int gdc_init_done = FALSE; - -/* local functions */ -static int map_gen_mode_num(int type, int color, int mode); -static int probe_adapters(void); - -#define prologue(adp, flag, err) \ - if (!gdc_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 < nitems(mode_map); ++i) { - if (mode_map[i].from == mode) - return mode_map[i].to; - } - return mode; -} - -static int -verify_adapter(video_adapter_t *adp) -{ -#ifndef GDC_NOGRAPHICS - int i; - - if (PC98_SYSTEM_PARAMETER(0x45c) & 0x40) { /* PEGC exists */ - adp->va_flags |= V_ADP_VESA; /* XXX */ - } else { - for (i = 0; bios_vmode[i].vi_mode != EOT; ++i) { - if (bios_vmode[i].vi_flags & V_INFO_VESA) - bios_vmode[i].vi_mode = NA; - } - } -#endif - return 0; -} - -/* 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 (gdc_init_done) - return 1; - gdc_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; - - if ((PC98_SYSTEM_PARAMETER(0x597) & 0x80) || - (PC98_SYSTEM_PARAMETER(0x458) & 0x80)) { - gdc_FH = (inb(0x9a8) & 1) ? _31KHZ : _24KHZ; - } else { - gdc_FH = _24KHZ; - } - - gdc_get_info(&biosadapter[0], biosadapter[0].va_initial_mode, &info); - initialize_gdc(T25_G400, info.vi_flags & V_INFO_GRAPHICS); - - 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; - if (info.vi_flags & V_INFO_GRAPHICS) { - switch (info.vi_depth/info.vi_planes) { - case 1: - biosadapter[0].va_line_width = info.vi_width/8; - break; - case 2: - biosadapter[0].va_line_width = info.vi_width/4; - break; - case 4: - biosadapter[0].va_line_width = info.vi_width/2; - break; - case 8: - default: /* shouldn't happen */ - biosadapter[0].va_line_width = info.vi_width; - break; - } - } else { - biosadapter[0].va_line_width = info.vi_width; - } - bcopy(&info, &biosadapter[0].va_info, sizeof(info)); - - verify_adapter(&biosadapter[0]); - - return 1; -} - -static void master_gdc_cmd(unsigned int cmd) -{ - while ( (inb(TEXT_GDC) & 2) != 0); - outb(TEXT_GDC+2, cmd); -} - -static void master_gdc_prm(unsigned int pmtr) -{ - while ( (inb(TEXT_GDC) & 2) != 0); - outb(TEXT_GDC, pmtr); -} - -static void master_gdc_word_prm(unsigned int wpmtr) -{ - master_gdc_prm(wpmtr & 0x00ff); - master_gdc_prm((wpmtr >> 8) & 0x00ff); -} - -#ifdef LINE30 -static void master_gdc_fifo_empty(void) -{ - while ( (inb(TEXT_GDC) & 4) == 0); -} -#endif - -static void master_gdc_wait_vsync(void) -{ - while ( (inb(TEXT_GDC) & 0x20) != 0); - while ( (inb(TEXT_GDC) & 0x20) == 0); -} - -static void gdc_cmd(unsigned int cmd) -{ - while ( (inb(GRAPHIC_GDC) & 2) != 0); - outb( GRAPHIC_GDC+2, cmd); -} - -#ifdef LINE30 -static void gdc_prm(unsigned int pmtr) -{ - while ( (inb(GRAPHIC_GDC) & 2) != 0); - outb( GRAPHIC_GDC, 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(GRAPHIC_GDC) & 0x04) == 0); -} -#endif - -static void gdc_wait_vsync(void) -{ - while ( (inb(GRAPHIC_GDC) & 0x20) != 0); - while ( (inb(GRAPHIC_GDC) & 0x20) == 0); -} - -#ifdef LINE30 -static int check_gdc_clock(void) -{ - if ((inb(IO_SYSPORT) & 0x80) == 0){ - return _5MHZ; - } else { - return _2_5MHZ; - } -} -#endif - -static void initialize_gdc(unsigned int mode, int isGraph) -{ -#ifdef LINE30 - /* start 30line initialize */ - int m_mode, s_mode, gdc_clock, hsync_clock; - - gdc_clock = check_gdc_clock(); - m_mode = (mode == T25_G400) ? _25L : _30L; - s_mode = 2*mode+gdc_clock; - gdc_INFO = m_mode; - - master_gdc_wait_vsync(); - - if ((PC98_SYSTEM_PARAMETER(0x597) & 0x80) || - (PC98_SYSTEM_PARAMETER(0x458) & 0x80)) { - if (PC98_SYSTEM_PARAMETER(0x481) & 0x08) { - hsync_clock = (m_mode == _25L) ? gdc_FH : _31KHZ; - outb(0x9a8, (hsync_clock == _31KHZ) ? 1 : 0); - } else { - hsync_clock = gdc_FH; - } - } else { - hsync_clock = _24KHZ; - } - - if ((gdc_clock == _2_5MHZ) && - (slave_param[hsync_clock][s_mode][GDC_LF] > 400)) { - outb(0x6a, 0x83); - outb(0x6a, 0x85); - gdc_clock = _5MHZ; - s_mode = 2*mode+gdc_clock; - } - - 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[hsync_clock][m_mode][GDC_CR]); - master_gdc_word_prm(((master_param[hsync_clock][m_mode][GDC_HFP] << 10) - + (master_param[hsync_clock][m_mode][GDC_VS] << 5) - + master_param[hsync_clock][m_mode][GDC_HS])); - master_gdc_prm(master_param[hsync_clock][m_mode][GDC_HBP]); - master_gdc_prm(master_param[hsync_clock][m_mode][GDC_VFP]); - master_gdc_word_prm(((master_param[hsync_clock][m_mode][GDC_VBP] << 10) - + (master_param[hsync_clock][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[hsync_clock][s_mode][GDC_CR]); - gdc_word_prm((slave_param[hsync_clock][s_mode][GDC_HFP] << 10) - + (slave_param[hsync_clock][s_mode][GDC_VS] << 5) - + (slave_param[hsync_clock][s_mode][GDC_HS])); - gdc_prm(slave_param[hsync_clock][s_mode][GDC_HBP]); - gdc_prm(slave_param[hsync_clock][s_mode][GDC_VFP]); - gdc_word_prm((slave_param[hsync_clock][s_mode][GDC_VBP] << 10) - + (slave_param[hsync_clock][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[hsync_clock][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(isGraph ? _GDC_START : _GDC_STOP); - - gdc_wait_vsync(); - gdc_wait_vsync(); - gdc_wait_vsync(); - - master_gdc_cmd(isGraph ? _GDC_STOP : _GDC_START); -#else - master_gdc_wait_vsync(); - master_gdc_cmd(isGraph ? _GDC_STOP : _GDC_START); /* text */ - gdc_wait_vsync(); - gdc_cmd(isGraph ? _GDC_START : _GDC_STOP); /* graphics */ -#endif -} - -#ifndef GDC_NOGRAPHICS -static u_char b_palette[] = { - /* R G B */ - 0x00, 0x00, 0x00, /* 0 */ - 0x00, 0x00, 0x7f, /* 1 */ - 0x7f, 0x00, 0x00, /* 2 */ - 0x7f, 0x00, 0x7f, /* 3 */ - 0x00, 0x7f, 0x00, /* 4 */ - 0x00, 0x7f, 0x7f, /* 5 */ - 0x7f, 0x7f, 0x00, /* 6 */ - 0x7f, 0x7f, 0x7f, /* 7 */ - 0x40, 0x40, 0x40, /* 8 */ - 0x00, 0x00, 0xff, /* 9 */ - 0xff, 0x00, 0x00, /* 10 */ - 0xff, 0x00, 0xff, /* 11 */ - 0x00, 0xff, 0x00, /* 12 */ - 0x00, 0xff, 0xff, /* 13 */ - 0xff, 0xff, 0x00, /* 14 */ - 0xff, 0xff, 0xff, /* 15 */ -}; -#endif - -static int -gdc_load_palette(video_adapter_t *adp, u_char *palette) -{ -#ifndef GDC_NOGRAPHICS - int i; - - if (adp->va_info.vi_flags & V_INFO_VESA) { - gdc_wait_vsync(); - for (i = 0; i < 256; ++i) { - outb(0xa8, i); - outb(0xac, *palette++); /* R */ - outb(0xaa, *palette++); /* G */ - outb(0xae, *palette++); /* B */ - } - } else { - /* - * XXX - Even though PC-98 text color is independent of palette, - * we should set palette in text mode. - * Because the background color of text mode is palette 0's one. - */ - outb(0x6a, 1); /* 16 colors mode */ - bcopy(palette, b_palette, sizeof(b_palette)); - - gdc_wait_vsync(); - for (i = 0; i < 16; ++i) { - outb(0xa8, i); - outb(0xac, *palette++ >> 4); /* R */ - outb(0xaa, *palette++ >> 4); /* G */ - outb(0xae, *palette++ >> 4); /* B */ - } - } -#endif - return 0; -} - -static int -gdc_save_palette(video_adapter_t *adp, u_char *palette) -{ -#ifndef GDC_NOGRAPHICS - int i; - - if (adp->va_info.vi_flags & V_INFO_VESA) { - for (i = 0; i < 256; ++i) { - outb(0xa8, i); - *palette++ = inb(0xac); /* R */ - *palette++ = inb(0xaa); /* G */ - *palette++ = inb(0xae); /* B */ - } - } else { - bcopy(b_palette, palette, sizeof(b_palette)); - } -#endif - return 0; -} - -static int -gdc_set_origin(video_adapter_t *adp, off_t offset) -{ -#ifndef GDC_NOGRAPHICS - if (adp->va_info.vi_flags & V_INFO_VESA) { - writew(BIOS_PADDRTOVADDR(0x000e0004), offset >> 15); - } -#endif - return 0; -} - -/* entry points */ - -static int -gdc_err(video_adapter_t *adp, ...) -{ - return ENODEV; -} - -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 (!gdc_init_done) - return ENXIO; - - 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]; - info->vi_buffer_size = info->vi_window_size*info->vi_planes; - return 0; - } - } - return EINVAL; -} - -/* - * 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) -{ - int i; - - if (!gdc_init_done) - return ENXIO; - - 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, info)) - continue; - return 0; - } - return ENODEV; -} - -/* - * 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, ENODEV); - - mode = map_gen_mode_num(adp->va_type, - adp->va_flags & V_ADP_COLOR, mode); - if (gdc_get_info(adp, mode, &info)) - return EINVAL; - - switch (info.vi_mode) { -#ifndef GDC_NOGRAPHICS - case M_PC98_PEGC640x480: /* PEGC 640x480 */ - initialize_gdc(T30_G480, info.vi_flags & V_INFO_GRAPHICS); - break; - case M_PC98_PEGC640x400: /* PEGC 640x400 */ - case M_PC98_EGC640x400: /* EGC GRAPHICS */ -#endif - case M_PC98_80x25: /* VGA TEXT */ - initialize_gdc(T25_G400, info.vi_flags & V_INFO_GRAPHICS); - break; - case M_PC98_80x30: /* VGA TEXT */ - initialize_gdc(T30_G400, info.vi_flags & V_INFO_GRAPHICS); - break; - default: - break; - } - -#ifndef GDC_NOGRAPHICS - if (info.vi_flags & V_INFO_VESA) { - outb(0x6a, 0x07); /* enable mode F/F change */ - outb(0x6a, 0x21); /* enhanced graphics */ - if (info.vi_height > 400) - outb(0x6a, 0x69); /* 800 lines */ - writeb(BIOS_PADDRTOVADDR(0x000e0100), 0); /* packed pixel */ - } else { - if (adp->va_flags & V_ADP_VESA) { - outb(0x6a, 0x07); /* enable mode F/F change */ - outb(0x6a, 0x20); /* normal graphics */ - outb(0x6a, 0x68); /* 400 lines */ - } - outb(0x6a, 1); /* 16 colors */ - } -#endif - - adp->va_mode = mode; - 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; - } - if (info.vi_flags & V_INFO_GRAPHICS) { - switch (info.vi_depth/info.vi_planes) { - case 1: - adp->va_line_width = info.vi_width/8; - break; - case 2: - adp->va_line_width = info.vi_width/4; - break; - case 4: - adp->va_line_width = info.vi_width/2; - break; - case 8: - default: /* shouldn't happen */ - adp->va_line_width = info.vi_width; - break; - } - } else { - adp->va_line_width = info.vi_width; - } - bcopy(&info, &adp->va_info, sizeof(info)); - - /* move hardware cursor out of the way */ - vidd_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 ENODEV; -} - -/* - * load_state(): - * Set video card registers at once. - */ -static int -gdc_load_state(video_adapter_t *adp, void *p) -{ - return ENODEV; -} - -/* - * 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) -{ - u_int16_t off; - int s; - - if (!gdc_init_done) - return ENXIO; - - if (adp->va_info.vi_flags & V_INFO_GRAPHICS) - return ENODEV; - - 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 / adp->va_info.vi_width; - *col = off % adp->va_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) -{ - u_int16_t off; - int s; - - if (!gdc_init_done) - return ENXIO; - - if ((col == -1) && (row == -1)) { - off = -1; - } else { - if (adp->va_info.vi_flags & V_INFO_GRAPHICS) - return ENODEV; - off = row*adp->va_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; - - if (!gdc_init_done) - return ENXIO; - - start = celsize - (base + height); - end = celsize - base - 1; - -#if 0 - /* - * 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) && (start < end)) - --end; -#endif - - 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 ? 0 : 0x20) /* blink on/off */ - | (start & 0x1f)); /* start line */ - splx(s); - - return 0; -} - -/* - * blank_display() - * Put the display in power save/power off mode. - */ -static int -gdc_blank_display(video_adapter_t *adp, int mode) -{ - int s; - static int standby = 0; - - if (!gdc_init_done) - return ENXIO; - - s = splhigh(); - switch (mode) { - case V_DISPLAY_SUSPEND: - case V_DISPLAY_STAND_BY: - outb(0x09a2, 0x80 | 0x40); /* V/H-SYNC mask */ - if (inb(0x09a2) == (0x80 | 0x40)) - standby = 1; - /* FALLTHROUGH */ - - case V_DISPLAY_BLANK: - while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */ - ; - outb(TEXT_GDC + 8, 0x0e); /* DISP off */ - break; - - case V_DISPLAY_ON: - while (!(inb(TEXT_GDC) & 0x20)) /* V-SYNC wait */ - ; - outb(TEXT_GDC + 8, 0x0f); /* DISP on */ - if (standby) { - outb(0x09a2, 0x00); /* V/H-SYNC unmask */ - standby = 0; - } - break; - } - splx(s); - return 0; -} - -/* - * mmap(): - * Mmap frame buffer. - */ -static int -gdc_mmap_buf(video_adapter_t *adp, vm_ooffset_t offset, vm_offset_t *paddr, - int prot, vm_memattr_t *memattr) -{ - /* FIXME: is this correct? XXX */ - if (offset > VIDEO_BUF_SIZE - PAGE_SIZE) - return -1; - *paddr = adp->va_info.vi_window + offset; - return 0; -} - -#ifndef GDC_NOGRAPHICS -static void -planar_fill(video_adapter_t *adp, int val) -{ - - outb(0x7c, 0x80); /* GRCG on & TDW mode */ - outb(0x7e, 0); /* tile B */ - outb(0x7e, 0); /* tile R */ - outb(0x7e, 0); /* tile G */ - outb(0x7e, 0); /* tile I */ - - fillw_io(0, adp->va_window, 0x8000 / 2); /* XXX */ - - outb(0x7c, 0); /* GRCG off */ -} - -static void -packed_fill(video_adapter_t *adp, int val) -{ - int length; - int at; /* position in the frame buffer */ - int l; - - at = 0; - length = adp->va_line_width*adp->va_info.vi_height; - while (length > 0) { - l = imin(length, adp->va_window_size); - vidd_set_win_org(adp, at); - bzero_io(adp->va_window, l); - length -= l; - at += l; - } -} - -static int -gdc_clear(video_adapter_t *adp) -{ - - switch (adp->va_info.vi_mem_model) { - case V_INFO_MM_TEXT: - /* do nothing? XXX */ - break; - case V_INFO_MM_PLANAR: - planar_fill(adp, 0); - break; - case V_INFO_MM_PACKED: - packed_fill(adp, 0); - break; - } - - return 0; -} -#else /* GDC_NOGRAPHICS */ -static int -gdc_clear(video_adapter_t *adp) -{ - - return 0; -} -#endif /* GDC_NOGRAPHICS */ - -static int -gdc_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy) -{ - return ENODEV; -} - -static int -gdc_bitblt(video_adapter_t *adp,...) -{ - /* FIXME */ - return ENODEV; -} - -static int -gdc_dev_ioctl(video_adapter_t *adp, u_long cmd, caddr_t arg) -{ - switch (cmd) { - case FBIO_GETWINORG: /* get frame buffer window origin */ - *(u_int *)arg = 0; - return 0; - - case FBIO_SETWINORG: /* set frame buffer window origin */ - case FBIO_SETDISPSTART: /* set display start address */ - case FBIO_SETLINEWIDTH: /* set scan line length in pixel */ - case FBIO_GETPALETTE: /* get color palette */ - case FBIO_SETPALETTE: /* set color palette */ - case FBIOGETCMAP: /* get color palette */ - case FBIOPUTCMAP: /* set color palette */ - return ENODEV; - - case FBIOGTYPE: /* get frame buffer type info. */ - ((struct fbtype *)arg)->fb_type = fb_type(adp->va_type); - ((struct fbtype *)arg)->fb_height = adp->va_info.vi_height; - ((struct fbtype *)arg)->fb_width = adp->va_info.vi_width; - ((struct fbtype *)arg)->fb_depth = adp->va_info.vi_depth; - if ((adp->va_info.vi_depth <= 1) || (adp->va_info.vi_depth > 8)) - ((struct fbtype *)arg)->fb_cmsize = 0; - else - ((struct fbtype *)arg)->fb_cmsize = 1 << adp->va_info.vi_depth; - ((struct fbtype *)arg)->fb_size = adp->va_buffer_size; - return 0; - - default: - return fb_commonioctl(adp, cmd, arg); - } -} - -/* - * 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) -{ -#if defined(FB_DEBUG) && FB_DEBUG > 1 - int i; -#endif - - if (!gdc_init_done) - return ENXIO; - - fb_dump_adp_info(DRIVER_NAME, adp, level); - -#if defined(FB_DEBUG) && 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; -} diff --git a/sys/pc98/cbus/nmi.c b/sys/pc98/cbus/nmi.c deleted file mode 100644 index 16612aa25b44..000000000000 --- a/sys/pc98/cbus/nmi.c +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * Copyright (c) 1991 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * 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. - * 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: @(#)isa.c 7.2 (Berkeley) 5/13/91 - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/syslog.h> -#include <sys/systm.h> - -#include <machine/md_var.h> - -#define NMI_PARITY 0x04 -#define NMI_EPARITY 0x02 - -/* - * Handle a NMI, possibly a machine check. - * return true to panic system, false to ignore. - */ -int -isa_nmi(int cd) -{ - int retval = 0; - int port = inb(0x33); - - log(LOG_CRIT, "NMI PC98 port = %x\n", port); - if (port & NMI_PARITY) { - log(LOG_CRIT, "BASE RAM parity error, likely hardware failure."); - retval = 1; - } else if (port & NMI_EPARITY) { - log(LOG_CRIT, "EXTENDED RAM parity error, likely hardware failure."); - retval = 1; - } else { - log(LOG_CRIT, "\nNMI Resume ??\n"); - } - - return(retval); -} diff --git a/sys/pc98/cbus/olpt.c b/sys/pc98/cbus/olpt.c deleted file mode 100644 index 983ec078e213..000000000000 --- a/sys/pc98/cbus/olpt.c +++ /dev/null @@ -1,648 +0,0 @@ -/*- - * Copyright (c) 1990 William F. Jolitz, TeleMuse - * 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 software is a component of "386BSD" developed by - * William F. Jolitz, TeleMuse. - * 4. Neither the name of the developer nor the name "386BSD" - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS A COMPONENT OF 386BSD DEVELOPED BY WILLIAM F. JOLITZ - * AND IS INTENDED FOR RESEARCH AND EDUCATIONAL PURPOSES ONLY. THIS - * SOFTWARE SHOULD NOT BE CONSIDERED TO BE A COMMERCIAL PRODUCT. - * THE DEVELOPER URGES THAT USERS WHO REQUIRE A COMMERCIAL PRODUCT - * NOT MAKE USE OF THIS WORK. - * - * FOR USERS WHO WISH TO UNDERSTAND THE 386BSD SYSTEM DEVELOPED - * BY WILLIAM F. JOLITZ, WE RECOMMEND THE USER STUDY WRITTEN - * REFERENCES SUCH AS THE "PORTING UNIX TO THE 386" SERIES - * (BEGINNING JANUARY 1991 "DR. DOBBS JOURNAL", USA AND BEGINNING - * JUNE 1991 "UNIX MAGAZIN", GERMANY) BY WILLIAM F. JOLITZ AND - * LYNNE GREER JOLITZ, AS WELL AS OTHER BOOKS ON UNIX AND THE - * ON-LINE 386BSD USER MANUAL BEFORE USE. A BOOK DISCUSSING THE INTERNALS - * OF 386BSD ENTITLED "386BSD FROM THE INSIDE OUT" WILL BE AVAILABLE LATE 1992. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``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 DEVELOPER 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: unknown origin, 386BSD 0.1 - * $FreeBSD$ - */ - -/* - * Device Driver for AT parallel printer port - * Written by William Jolitz 12/18/90 - */ - -/* - * Parallel port TCP/IP interfaces added. I looked at the driver from - * MACH but this is a complete rewrite, and btw. incompatible, and it - * should perform better too. I have never run the MACH driver though. - * - * This driver sends two bytes (0x08, 0x00) in front of each packet, - * to allow us to distinguish another format later. - * - * Now added a Linux/Crynwr compatibility mode which is enabled using - * IF_LINK0 - Tim Wilkinson. - * - * TODO: - * Make HDLC/PPP mode, use IF_LLC1 to enable. - * - * Connect the two computers using a Laplink parallel cable to use this - * feature: - * - * +----------------------------------------+ - * |A-name A-End B-End Descr. Port/Bit | - * +----------------------------------------+ - * |DATA0 2 15 Data 0/0x01 | - * |-ERROR 15 2 1/0x08 | - * +----------------------------------------+ - * |DATA1 3 13 Data 0/0x02 | - * |+SLCT 13 3 1/0x10 | - * +----------------------------------------+ - * |DATA2 4 12 Data 0/0x04 | - * |+PE 12 4 1/0x20 | - * +----------------------------------------+ - * |DATA3 5 10 Strobe 0/0x08 | - * |-ACK 10 5 1/0x40 | - * +----------------------------------------+ - * |DATA4 6 11 Data 0/0x10 | - * |BUSY 11 6 1/~0x80 | - * +----------------------------------------+ - * |GND 18-25 18-25 GND - | - * +----------------------------------------+ - * - * Expect transfer-rates up to 75 kbyte/sec. - * - * If GCC could correctly grok - * register int port asm("edx") - * the code would be cleaner - * - * Poul-Henning Kamp <phk@freebsd.org> - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/conf.h> -#include <sys/bus.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/uio.h> -#include <sys/syslog.h> -#include <sys/malloc.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <isa/isavar.h> - -#include <pc98/cbus/olptreg.h> -#include <dev/ppbus/lptio.h> - -#define LPINITRDY 4 /* wait up to 4 seconds for a ready */ -#define LPTOUTINITIAL 10 /* initial timeout to wait for ready 1/10 s */ -#define LPTOUTMAX 1 /* maximal timeout 1 s */ -#define LPPRI (PZERO+8) -#define BUFSIZE 1024 - -#ifndef DEBUG -#define lprintf(args) -#else -#define lprintf(args) do { \ - if (lptflag) \ - printf args; \ - } while (0) -static int volatile lptflag = 1; -#endif - -struct lpt_softc { - struct resource *res_port; - struct resource *res_irq; - void *sc_ih; - struct callout timer; - - int sc_port; - short sc_state; - /* default case: negative prime, negative ack, handshake strobe, - prime once */ - u_char sc_control; - char sc_flags; -#define LP_POS_INIT 0x04 /* if we are a postive init signal */ -#define LP_POS_ACK 0x08 /* if we are a positive going ack */ -#define LP_NO_PRIME 0x10 /* don't prime the printer at all */ -#define LP_PRIMEOPEN 0x20 /* prime on every open */ -#define LP_AUTOLF 0x40 /* tell printer to do an automatic lf */ -#define LP_BYPASS 0x80 /* bypass printer ready checks */ - void *sc_inbuf; - short sc_xfercnt ; - char sc_primed; - char *sc_cp ; - u_char sc_irq ; /* IRQ status of port */ -#define LP_HAS_IRQ 0x01 /* we have an irq available */ -#define LP_USE_IRQ 0x02 /* we are using our irq */ -#define LP_ENABLE_IRQ 0x04 /* enable IRQ on open */ - u_char sc_backoff ; /* time to call lptout() again */ -}; - -/* bits for state */ -#define OPEN (1<<0) /* device is open */ -#define ASLP (1<<1) /* awaiting draining of printer */ -#define ERROR (1<<2) /* error was received from printer */ -#define OBUSY (1<<3) /* printer is busy doing output */ -#define LPTOUT (1<<4) /* timeout while not selected */ -#define TOUT (1<<5) /* timeout while not selected */ -#define INIT (1<<6) /* waiting to initialize for open */ -#define INTERRUPTED (1<<7) /* write call was interrupted */ - - -/* status masks to interrogate printer status */ -#define RDY_MASK (LPS_SEL|LPS_OUT|LPS_NBSY|LPS_NERR) /* ready ? */ -#define LP_READY (LPS_SEL|LPS_NBSY|LPS_NERR) - -/* Printer Ready condition - from lpa.c */ -/* Only used in polling code */ -#define NOT_READY(x) ((inb(x) & LPS_NBSY) != LPS_NBSY) - -#define MAX_SLEEP (hz*5) /* Timeout while waiting for device ready */ -#define MAX_SPIN 20 /* Max delay for device ready in usecs */ - -static timeout_t lptout; -static int lpt_probe(device_t); -static int lpt_attach(device_t); -static void lpt_intr(void *); - -static devclass_t olpt_devclass; - -static device_method_t olpt_methods[] = { - DEVMETHOD(device_probe, lpt_probe), - DEVMETHOD(device_attach, lpt_attach), - { 0, 0 } -}; - -static driver_t olpt_driver = { - "olpt", - olpt_methods, - sizeof (struct lpt_softc), -}; - -DRIVER_MODULE(olpt, isa, olpt_driver, olpt_devclass, 0, 0); - -static d_open_t lptopen; -static d_close_t lptclose; -static d_write_t lptwrite; -static d_ioctl_t lptioctl; - -static struct cdevsw lpt_cdevsw = { - .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, - .d_open = lptopen, - .d_close = lptclose, - .d_write = lptwrite, - .d_ioctl = lptioctl, - .d_name = "lpt", -}; - -static bus_addr_t lpt_iat[] = {0, 2, 4, 6}; - -/* - * New lpt port probe Geoff Rehmet - Rhodes University - 14/2/94 - * Based partially on Rod Grimes' printer probe - * - * Logic: - * 1) If no port address was given, use the bios detected ports - * and autodetect what ports the printers are on. - * 2) Otherwise, probe the data port at the address given, - * using the method in Rod Grimes' port probe. - * (Much code ripped off directly from Rod's probe.) - * - * Comments from Rod's probe: - * Logic: - * 1) You should be able to write to and read back the same value - * to the data port. Do an alternating zeros, alternating ones, - * walking zero, and walking one test to check for stuck bits. - * - * 2) You should be able to write to and read back the same value - * to the control port lower 5 bits, the upper 3 bits are reserved - * per the IBM PC technical reference manauls and different boards - * do different things with them. Do an alternating zeros, alternating - * ones, walking zero, and walking one test to check for stuck bits. - * - * Some printers drag the strobe line down when the are powered off - * so this bit has been masked out of the control port test. - * - * XXX Some printers may not like a fast pulse on init or strobe, I - * don't know at this point, if that becomes a problem these bits - * should be turned off in the mask byte for the control port test. - * - * We are finally left with a mask of 0x14, due to some printers - * being adamant about holding other bits high ........ - * - * Before probing the control port, we write a 0 to the data port - - * If not, some printers chuck out garbage when the strobe line - * gets toggled. - * - * 3) Set the data and control ports to a value of 0 - * - * This probe routine has been tested on Epson Lx-800, HP LJ3P, - * Epson FX-1170 and C.Itoh 8510RM - * printers. - * Quick exit on fail added. - */ - -int -lpt_probe(device_t dev) -{ -#define PC98_OLD_LPT 0x40 -#define PC98_IEEE_1284_FUNCTION 0x149 - int rid; - struct resource *res; - - /* Check isapnp ids */ - if (isa_get_vendorid(dev)) - return ENXIO; - - rid = 0; - res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, lpt_iat, 4, - RF_ACTIVE); - if (res == NULL) - return ENXIO; - isa_load_resourcev(res, lpt_iat, 4); - - if (isa_get_port(dev) == PC98_OLD_LPT) { - unsigned int pc98_ieee_mode, tmp; - - tmp = inb(PC98_IEEE_1284_FUNCTION); - pc98_ieee_mode = tmp; - if ((tmp & 0x10) == 0x10) { - outb(PC98_IEEE_1284_FUNCTION, tmp & ~0x10); - tmp = inb(PC98_IEEE_1284_FUNCTION); - if ((tmp & 0x10) != 0x10) { - outb(PC98_IEEE_1284_FUNCTION, pc98_ieee_mode); - bus_release_resource(dev, SYS_RES_IOPORT, rid, - res); - return ENXIO; - } - } - } - - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - return 0; -} - -/* XXX Todo - try and detect if interrupt is working */ -int -lpt_attach(device_t dev) -{ - int rid, unit; - struct lpt_softc *sc; - struct cdev *cdev; - - unit = device_get_unit(dev); - sc = device_get_softc(dev); - callout_init(&sc->timer, 0); - - rid = 0; - sc->res_port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, - lpt_iat, 4, RF_ACTIVE); - if (sc->res_port == NULL) - return ENXIO; - isa_load_resourcev(sc->res_port, lpt_iat, 4); - - sc->sc_port = rman_get_start(sc->res_port); - sc->sc_primed = 0; /* not primed yet */ - - outb(sc->sc_port+lpt_pstb_ctrl, LPC_DIS_PSTB); /* PSTB disable */ - outb(sc->sc_port+lpt_control, LPC_MODE8255); /* 8255 mode set */ - outb(sc->sc_port+lpt_control, LPC_NIRQ8); /* IRQ8 inactive */ - outb(sc->sc_port+lpt_control, LPC_NPSTB); /* PSTB inactive */ - outb(sc->sc_port+lpt_pstb_ctrl, LPC_EN_PSTB); /* PSTB enable */ - - sc->sc_irq = 0; - if (isa_get_irq(dev) != -1) { - rid = 0; - sc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (sc->res_irq == NULL) { - bus_release_resource(dev, SYS_RES_IOPORT, 0, - sc->res_port); - return ENXIO; - } - if (bus_setup_intr(dev, sc->res_irq, INTR_TYPE_TTY, NULL, lpt_intr, - sc, &sc->sc_ih)) { - bus_release_resource(dev, SYS_RES_IOPORT, 0, - sc->res_port); - bus_release_resource(dev, SYS_RES_IRQ, 0, - sc->res_irq); - return ENXIO; - } - sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ; - device_printf(dev, "Interrupt-driven port"); - } - - cdev = make_dev(&lpt_cdevsw, 0, - UID_ROOT, GID_WHEEL, 0600, "lpt%d", unit); - cdev->si_drv1 = sc; - cdev = make_dev(&lpt_cdevsw, LP_BYPASS, - UID_ROOT, GID_WHEEL, 0600, "lpctl%d", unit); - cdev->si_drv1 = sc; - - return 0; -} - -/* - * lptopen -- reset the printer, then wait until it's selected and not busy. - * If LP_BYPASS flag is selected, then we do not try to select the - * printer -- this is just used for passing ioctls. - */ - -static int -lptopen (struct cdev *dev, int flags, int fmt, struct thread *td) -{ - struct lpt_softc *sc = dev->si_drv1; - int s; - int port; - - if (sc->sc_port == 0) - return (ENXIO); - - if (sc->sc_state) { - lprintf(("lp: still open %x\n", sc->sc_state)); - return(EBUSY); - } else - sc->sc_state |= INIT; - - sc->sc_flags = dev2unit(dev); - - /* Check for open with BYPASS flag set. */ - if (sc->sc_flags & LP_BYPASS) { - sc->sc_state = OPEN; - return(0); - } - - s = spltty(); - lprintf(("lp flags 0x%x\n", sc->sc_flags)); - port = sc->sc_port; - - /* set IRQ status according to ENABLE_IRQ flag */ - if (sc->sc_irq & LP_ENABLE_IRQ) - sc->sc_irq |= LP_USE_IRQ; - else - sc->sc_irq &= ~LP_USE_IRQ; - - /* init printer */ - sc->sc_state = OPEN; - sc->sc_inbuf = malloc(BUFSIZE, M_DEVBUF, M_WAITOK); - sc->sc_xfercnt = 0; - splx(s); - - /* only use timeout if using interrupt */ - lprintf(("irq %x\n", sc->sc_irq)); - if (sc->sc_irq & LP_USE_IRQ) { - sc->sc_state |= TOUT; - sc->sc_backoff = hz / LPTOUTINITIAL; - callout_reset(&sc->timer, sc->sc_backoff, lptout, sc); - } - - lprintf(("opened.\n")); - return(0); -} - -static void -lptout (void *arg) -{ - struct lpt_softc *sc = arg; - int pl; - - lprintf(("T %x ", inb(sc->sc_port+lpt_status))); - if (sc->sc_state & OPEN) { - sc->sc_backoff++; - if (sc->sc_backoff > hz/LPTOUTMAX) - sc->sc_backoff = sc->sc_backoff > hz/LPTOUTMAX; - callout_reset(&sc->timer, sc->sc_backoff, lptout, sc); - } else - sc->sc_state &= ~TOUT; - - if (sc->sc_state & ERROR) - sc->sc_state &= ~ERROR; - - /* - * Avoid possible hangs do to missed interrupts - */ - if (sc->sc_xfercnt) { - pl = spltty(); - lpt_intr(sc); - splx(pl); - } else { - sc->sc_state &= ~OBUSY; - wakeup(sc); - } -} - -/* - * lptclose -- close the device, free the local line buffer. - * - * Check for interrupted write call added. - */ - -static int -lptclose(struct cdev *dev, int flags, int fmt, struct thread *td) -{ - struct lpt_softc *sc = dev->si_drv1; - - if(sc->sc_flags & LP_BYPASS) - goto end_close; - - sc->sc_state &= ~OPEN; - free(sc->sc_inbuf, M_DEVBUF); - -end_close: - sc->sc_state = 0; - sc->sc_xfercnt = 0; - lprintf(("closed.\n")); - return(0); -} - -/* - * pushbytes() - * Workhorse for actually spinning and writing bytes to printer - * Derived from lpa.c - * Originally by ? - * - * This code is only used when we are polling the port - */ -static int -pushbytes(struct lpt_softc * sc) -{ - int spin, err, tic; - char ch; - int port = sc->sc_port; - - lprintf(("p")); - /* loop for every character .. */ - while (sc->sc_xfercnt > 0) { - /* printer data */ - ch = *(sc->sc_cp); - sc->sc_cp++; - sc->sc_xfercnt--; - - /* - * Wait for printer ready. - * Loop 20 usecs testing BUSY bit, then sleep - * for exponentially increasing timeout. (vak) - */ - for (spin=0; NOT_READY(port+lpt_status) && spin<MAX_SPIN; ++spin) - DELAY(1); /* XXX delay is NOT this accurate! */ - if (spin >= MAX_SPIN) { - tic = 0; - while (NOT_READY(port+lpt_status)) { - /* - * Now sleep, every cycle a - * little longer .. - */ - tic = tic + tic + 1; - /* - * But no more than 10 seconds. (vak) - */ - if (tic > MAX_SLEEP) - tic = MAX_SLEEP; - err = tsleep(sc, LPPRI, - "lptpoll", tic); - if (err != EWOULDBLOCK) { - return (err); - } - } - } - - /* output data */ - outb(port+lpt_data, ch); - DELAY(1); - outb(port+lpt_control, LPC_PSTB); - DELAY(1); - outb(port+lpt_control, LPC_NPSTB); - } - return(0); -} - -/* - * lptwrite --copy a line from user space to a local buffer, then call - * putc to get the chars moved to the output queue. - * - * Flagging of interrupted write added. - */ - -static int -lptwrite(struct cdev *dev, struct uio * uio, int ioflag) -{ - register unsigned n; - int pl, err; - struct lpt_softc *sc = dev->si_drv1; - - if(sc->sc_flags & LP_BYPASS) { - /* we can't do writes in bypass mode */ - return(EPERM); - } - - sc->sc_state &= ~INTERRUPTED; - while ((n = min(BUFSIZE, uio->uio_resid)) != 0) { - sc->sc_cp = sc->sc_inbuf; - uiomove(sc->sc_cp, n, uio); - sc->sc_xfercnt = n ; - while ((sc->sc_xfercnt > 0)&&(sc->sc_irq & LP_USE_IRQ)) { - 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)); - pl = spltty(); - lpt_intr(sc); - (void) splx(pl); - } - lprintf(("W ")); - if (sc->sc_state & OBUSY) - if ((err = tsleep (sc, - LPPRI|PCATCH, "lpwrite", 0))) { - sc->sc_state |= INTERRUPTED; - return(err); - } - } - /* check to see if we must do a polled write */ - if(!(sc->sc_irq & LP_USE_IRQ) && (sc->sc_xfercnt)) { - lprintf(("p")); - if((err = pushbytes(sc))) - return(err); - } - } - return(0); -} - -/* - * lptintr -- handle printer interrupts which occur when the printer is - * ready to accept another char. - * - * do checking for interrupted write call. - */ - -static void -lpt_intr(void *arg) -{ -} - -static int -lptioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td) -{ - int error = 0; - struct lpt_softc *sc = dev->si_drv1; - u_char old_sc_irq; /* old printer IRQ status */ - - switch (cmd) { - case LPT_IRQ : - if(sc->sc_irq & LP_HAS_IRQ) { - /* - * NOTE: - * If the IRQ status is changed, - * this will only be visible on the - * next open. - * - * If interrupt status changes, - * this gets syslog'd. - */ - old_sc_irq = sc->sc_irq; - if(*(int*)data == 0) - sc->sc_irq &= (~LP_ENABLE_IRQ); - else - sc->sc_irq |= LP_ENABLE_IRQ; - if (old_sc_irq != sc->sc_irq ) - log(LOG_NOTICE, "%s switched to %s mode\n", - devtoname(dev), - (sc->sc_irq & LP_ENABLE_IRQ)? - "interrupt-driven":"polled"); - } else /* polled port */ - error = EOPNOTSUPP; - break; - default: - error = ENODEV; - } - - return(error); -} diff --git a/sys/pc98/cbus/olptreg.h b/sys/pc98/cbus/olptreg.h deleted file mode 100644 index 80bc704f006c..000000000000 --- a/sys/pc98/cbus/olptreg.h +++ /dev/null @@ -1,48 +0,0 @@ -/*- - * Copyright (c) 2005 TAKAHASHI Yoshihiro - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * $FreeBSD$ - */ - -/* - * modified for PC9801 by A.Kojima - * Kyoto University Microcomputer Club (KMC) - */ - -#define lpt_pstb_ctrl (-9) /* PSTB enable control */ -#define LPC_EN_PSTB 0xc /* PSTB enable */ -#define LPC_DIS_PSTB 0xd /* PSTB disable */ - -#define lpt_data 0 /* Data to/from printer (R/W) */ - -#define lpt_status 2 /* Status of printer (R) */ -#define LPS_NBSY 0x4 /* printer no ack of data */ - -#define lpt_control 6 /* Control printer (W) */ -#define LPC_MODE8255 0x82 /* 8255 mode */ -#define LPC_IRQ8 0x6 /* IRQ8 active */ -#define LPC_NIRQ8 0x7 /* IRQ8 inactive */ -#define LPC_PSTB 0xe /* PSTB active */ -#define LPC_NPSTB 0xf /* PSTB inactive */ diff --git a/sys/pc98/cbus/pckbd.c b/sys/pc98/cbus/pckbd.c deleted file mode 100644 index aec0f0dd2849..000000000000 --- a/sys/pc98/cbus/pckbd.c +++ /dev/null @@ -1,999 +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. - * - * $FreeBSD$ - */ - -#include "opt_compat.h" -#include "opt_kbd.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <machine/bus.h> -#include <sys/rman.h> -#include <sys/kbio.h> - -#include <machine/resource.h> - -#include <dev/kbd/kbdreg.h> - -#include <pc98/cbus/cbus.h> -#include <isa/isavar.h> - -#define DRIVER_NAME "pckbd" - -/* device configuration flags */ -#define KB_CONF_FAIL_IF_NO_KBD (1 << 0) /* don't install if no kbd is found */ - -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) */ - struct callout ks_timer; -} pckbd_state_t; - -static devclass_t pckbd_devclass; - -static int pckbdprobe(device_t dev); -static int pckbdattach(device_t dev); -static int pckbdresume(device_t dev); -static void pckbd_isa_intr(void *arg); - -static device_method_t pckbd_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pckbdprobe), - DEVMETHOD(device_attach, pckbdattach), - DEVMETHOD(device_resume, pckbdresume), - { 0, 0 } -}; - -static driver_t pckbd_driver = { - DRIVER_NAME, - pckbd_methods, - 1, -}; - -DRIVER_MODULE(pckbd, isa, pckbd_driver, pckbd_devclass, 0, 0); - -static bus_addr_t pckbd_iat[] = {0, 2}; - -static int pckbd_probe_unit(device_t dev, int port, int irq, - int flags); -static int pckbd_attach_unit(device_t dev, keyboard_t **kbd, - int port, int irq, int flags); -static timeout_t pckbd_timeout; - - -static int -pckbdprobe(device_t dev) -{ - struct resource *res; - int error, rid; - - /* Check isapnp ids */ - if (isa_get_vendorid(dev)) - return (ENXIO); - - device_set_desc(dev, "PC-98 Keyboard"); - - rid = 0; - res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, pckbd_iat, 2, - RF_ACTIVE); - if (res == NULL) - return ENXIO; - isa_load_resourcev(res, pckbd_iat, 2); - - error = pckbd_probe_unit(dev, - isa_get_port(dev), - (1 << isa_get_irq(dev)), - device_get_flags(dev)); - - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); - - return (error); -} - -static int -pckbdattach(device_t dev) -{ - keyboard_t *kbd; - void *ih; - struct resource *res; - int error, rid; - - rid = 0; - res = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, pckbd_iat, 2, - RF_ACTIVE); - if (res == NULL) - return ENXIO; - isa_load_resourcev(res, pckbd_iat, 2); - - error = pckbd_attach_unit(dev, &kbd, - isa_get_port(dev), - (1 << isa_get_irq(dev)), - device_get_flags(dev)); - - rid = 0; - res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (res == NULL) - return ENXIO; - bus_setup_intr(dev, res, INTR_TYPE_TTY, NULL, pckbd_isa_intr, kbd, &ih); - - return 0; -} - -static int -pckbdresume(device_t dev) -{ - keyboard_t *kbd; - - kbd = kbd_get_keyboard(kbd_find_keyboard(DRIVER_NAME, - device_get_unit(dev))); - if (kbd) - kbdd_clear_state(kbd); - - return (0); -} - -static void -pckbd_isa_intr(void *arg) -{ - keyboard_t *kbd = arg; - - kbdd_intr(kbd, NULL); -} - -static int -pckbd_probe_unit(device_t dev, int port, int irq, int flags) -{ - keyboard_switch_t *sw; - int args[2]; - int error; - - sw = kbd_get_switch(DRIVER_NAME); - if (sw == NULL) - return ENXIO; - - args[0] = port; - args[1] = irq; - error = (*sw->probe)(device_get_unit(dev), args, flags); - if (error) - return error; - return 0; -} - -static int -pckbd_attach_unit(device_t dev, keyboard_t **kbd, int port, int irq, int flags) -{ - keyboard_switch_t *sw; - pckbd_state_t *state; - int args[2]; - int error; - int unit; - - sw = kbd_get_switch(DRIVER_NAME); - if (sw == NULL) - return ENXIO; - - /* reset, initialize and enable the device */ - unit = device_get_unit(dev); - args[0] = port; - args[1] = irq; - *kbd = NULL; - error = (*sw->probe)(unit, args, flags); - if (error) - return error; - error = (*sw->init)(unit, kbd, args, flags); - if (error) - return error; - (*sw->enable)(*kbd); - -#ifdef KBD_INSTALL_CDEV - /* attach a virtual keyboard cdev */ - error = kbd_attach(*kbd); - 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 - */ - state = (pckbd_state_t *)(*kbd)->kb_data; - callout_init(&state->ks_timer, 0); - pckbd_timeout(*kbd); - - if (bootverbose) - (*sw->diag)(*kbd, bootverbose); - - return 0; -} - -static void -pckbd_timeout(void *arg) -{ - pckbd_state_t *state; - 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 (kbdd_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. - */ - kbdd_lock(kbd, FALSE); - if (kbdd_check_char(kbd)) - kbdd_intr(kbd, NULL); - } - splx(s); - state = (pckbd_state_t *)kbd->kb_data; - callout_reset(&state->ks_timer, hz / 10, pckbd_timeout, arg); -} - -/* LOW-LEVEL */ - -#include <sys/limits.h> - -#define PC98KBD_DEFAULT 0 - -/* 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; -static kbd_poll_mode_t pckbd_poll; - -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, - pckbd_poll, - 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 <pc98/cbus/pckbdtables.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; - int arg[2]; - int i; - - /* XXX: a kludge to obtain the device configuration flags */ - if (resource_int_value(DRIVER_NAME, 0, "flags", &i) == 0) { - flags |= i; - /* if the driver is disabled, unregister the keyboard if any */ - if (resource_disabled(DRIVER_NAME, 0)) { - i = kbd_find_keyboard(DRIVER_NAME, PC98KBD_DEFAULT); - if (i >= 0) { - kbd = kbd_get_keyboard(i); - kbd_unregister(kbd); - kbd->kb_flags &= ~KB_REGISTERED; - return 0; - } - } - } - - /* probe the default keyboard */ - arg[0] = -1; - arg[1] = -1; - kbd = NULL; - if (pckbd_probe(PC98KBD_DEFAULT, arg, flags)) - return 0; - if (pckbd_init(PC98KBD_DEFAULT, &kbd, arg, flags)) - return 0; - - /* return the number of found keyboards */ - return 1; -} - -/* low-level functions */ - -/* detect a keyboard */ -static int -pckbd_probe(int unit, void *arg, int flags) -{ - KBDC kbdc; - int *data = (int *)arg; - - if (unit != PC98KBD_DEFAULT) - return ENXIO; - if (KBD_IS_PROBED(&default_kbd)) - return 0; - - kbdc = kbdc_open(data[0]); - if (kbdc == NULL) - return ENXIO; - if (probe_keyboard(kbdc, flags)) { - if (flags & KB_CONF_FAIL_IF_NO_KBD) - return ENXIO; - } - return 0; -} - -/* reset and initialize the device */ -static int -pckbd_init(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; - int *data = (int *)arg; - - if (unit != PC98KBD_DEFAULT) /* shouldn't happen */ - return ENXIO; - - *kbdp = kbd = &default_kbd; - state = &default_kbd_state; - if (!KBD_IS_PROBED(kbd)) { - keymap = &default_keymap; - accmap = &default_accentmap; - fkeymap = default_fkeytab; - fkeymap_size = nitems(default_fkeytab); - - state->kbdc = kbdc_open(data[0]); - if (state->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(state->kbdc, flags)) {/* shouldn't happen */ - 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); - } - if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) { - if (KBD_HAS_DEVICE(kbd) - && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config) - && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) - return ENXIO; - pckbd_ioctl(kbd, KDSETLED, (caddr_t)&state->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) -{ - pckbd_state_t *state = (pckbd_state_t *)kbd->kb_data; - - kbd_unregister(kbd); - callout_drain(&state->ks_timer); - return 0; -} - -/* keyboard interrupt routine */ -static int -pckbd_intr(keyboard_t *kbd, void *arg) -{ - 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); - if (c != -1) - ++kbd->kb_count; - 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; - } - ++kbd->kb_count; - -#if 0 - printf("pckbd_read_char(): scancode:0x%x\n", scancode); -#endif - - /* 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; -#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD4) || defined(COMPAT_43) - int ival; -#endif - - s = spltty(); - switch (cmd) { - - case KDGKBMODE: /* get keyboard mode */ - *(int *)arg = state->ks_mode; - break; -#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD4) || defined(COMPAT_43) - case _IO('K', 7): - ival = IOCPARM_IVAL(arg); - arg = (caddr_t)&ival; - /* FALLTHROUGH */ -#endif - 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); - } - /* FALLTHROUGH */ - 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; -#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD4) || defined(COMPAT_43) - case _IO('K', 66): - ival = IOCPARM_IVAL(arg); - arg = (caddr_t)&ival; - /* FALLTHROUGH */ -#endif - 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; -#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \ - defined(COMPAT_FREEBSD4) || defined(COMPAT_43) - case _IO('K', 20): - ival = IOCPARM_IVAL(arg); - arg = (caddr_t)&ival; - /* FALLTHROUGH */ -#endif - 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 (old interface)*/ - break; - case KDSETREPEAT: /* set keyboard repeat rate (new interface) */ - break; - - case PIO_KEYMAP: /* set keyboard translation table */ - case OPIO_KEYMAP: /* set keyboard translation table (compat) */ - case PIO_KEYMAPENT: /* set keyboard translation table entry */ - case PIO_DEADKEYMAP: /* set accent key translation table */ - state->ks_accents = 0; - /* FALLTHROUGH */ - 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; -} - -/* set polling mode */ -static int -pckbd_poll(keyboard_t *kbd, int on) -{ - 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[1] = { { 0 }, }; - -/* associate a port number with a KBDC */ - -static KBDC -kbdc_open(int port) -{ - if (port <= 0) - port = IO_KBD; - - /* PC-98 has only one keyboard I/F */ - kbdc_softc[0].port = port; - kbdc_softc[0].lock = FALSE; - return (KBDC)&kbdc_softc[0]; -} - -/* 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 */ -} diff --git a/sys/pc98/cbus/pckbdtables.h b/sys/pc98/cbus/pckbdtables.h deleted file mode 100644 index 5386f52174eb..000000000000 --- a/sys/pc98/cbus/pckbdtables.h +++ /dev/null @@ -1,203 +0,0 @@ -/*- - * Copyright (C) 2005 TAKAHASHI Yoshihiro. 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. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR 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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#ifndef KBD_DFLT_KEYMAP - -#define NO_ACCENTCHARS - -/* PC-9801 keymap by kuribo@isl.melco.co.jp */ -static keymap_t key_map = { 0x80, { /* PC98 keymap */ -/* alt - * scan cntrl alt alt cntrl - * code base shift cntrl shift alt shift cntrl shift spcl flgs - * --------------------------------------------------------------------------- - */ -{{/*00*/ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, DBG, 0x1B }, 0x02,0x00 }, -{{/*01*/ '1', '!', '!', '!', '1', '!', '!', '!' }, 0x00,0x00 }, -{{/*02*/ '2', '\"', 0x1A, 0x1A, '2', '@', 0x00, 0x00 }, 0x00,0x00 }, -{{/*03*/ '3', '#', 0x1B, 0x1B, '3', '#', 0x1B, 0x1B }, 0x00,0x00 }, -{{/*04*/ '4', '$', 0x1C, 0x1C, '4', '$', 0x1C, 0x1C }, 0x00,0x00 }, -{{/*05*/ '5', '%', 0x1D, 0x1D, '5', '%', 0x1D, 0x1D }, 0x00,0x00 }, -{{/*06*/ '6', '&', 0x1E, 0x1E, '6', '^', 0x1E, 0x1E }, 0x00,0x00 }, -{{/*07*/ '7', '\'', 0x1F, 0x1F, '7', '&', '&', '&' }, 0x00,0x00 }, -{{/*08*/ '8', '(', 0x7F, 0x7F, '8', '*', 0x08, 0x08 }, 0x00,0x00 }, -{{/*09*/ '9', ')', '9', '9', '9', '(', '(', '(' }, 0x00,0x00 }, -{{/*0a*/ '0', NOP, '0', '0', '0', ')', ')', ')' }, 0x40,0x00 }, -{{/*0b*/ '-', '=', '-', '-', '-', '_', 0x1F, 0x1F }, 0x00,0x00 }, -{{/*0c*/ '^', '`', 0x1E, 0x1E, '=', '+', '+', '+' }, 0x00,0x00 }, -{{/*0d*/ '\\', '|', 0x1C, 0x1C, '\\', '|', 0x1C, 0x1C }, 0x00,0x00 }, -{{/*0e*/ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 }, 0x00,0x00 }, -{{/*0f*/ '\t', BTAB, '\t', BTAB, '\t', BTAB, '\t', BTAB }, 0x55,0x00 }, -{{/*10*/ 'q', 'Q', 0x11, 0x11, 'q', 'Q', 0x11, 0x11 }, 0x00,0x01 }, -{{/*11*/ 'w', 'W', 0x17, 0x17, 'w', 'W', 0x17, 0x17 }, 0x00,0x01 }, -{{/*12*/ 'e', 'E', 0x05, 0x05, 'e', 'E', 0x05, 0x05 }, 0x00,0x01 }, -{{/*13*/ 'r', 'R', 0x12, 0x12, 'r', 'R', 0x12, 0x12 }, 0x00,0x01 }, -{{/*14*/ 't', 'T', 0x14, 0x14, 't', 'T', 0x14, 0x14 }, 0x00,0x01 }, -{{/*15*/ 'y', 'Y', 0x19, 0x19, 'y', 'Y', 0x19, 0x19 }, 0x00,0x01 }, -{{/*16*/ 'u', 'U', 0x15, 0x15, 'u', 'U', 0x15, 0x15 }, 0x00,0x01 }, -{{/*17*/ 'i', 'I', 0x09, 0x09, 'i', 'I', 0x09, 0x09 }, 0x00,0x01 }, -{{/*18*/ 'o', 'O', 0x0F, 0x0F, 'o', 'O', 0x0F, 0x0F }, 0x00,0x01 }, -{{/*19*/ 'p', 'P', 0x10, 0x10, 'p', 'P', 0x10, 0x10 }, 0x00,0x01 }, -{{/*1a*/ '@', '~', 0x00, 0x00, '[', '{', 0x1B, 0x1B }, 0x00,0x00 }, -{{/*1b*/ '[', '{', 0x1B, 0x1B, ']', '}', 0x1D, 0x1D }, 0x00,0x00 }, -{{/*1c*/ '\r', '\r', '\n', '\n', '\r', '\r', '\n', '\n' }, 0x00,0x00 }, -{{/*1d*/ 'a', 'A', 0x01, 0x01, 'a', 'A', 0x01, 0x01 }, 0x00,0x01 }, -{{/*1e*/ 's', 'S', 0x13, 0x13, 's', 'S', 0x13, 0x13 }, 0x00,0x01 }, -{{/*1f*/ 'd', 'D', 0x04, 0x04, 'd', 'D', 0x04, 0x04 }, 0x00,0x01 }, -{{/*20*/ 'f', 'F', 0x06, 0x06, 'f', 'F', 0x06, 0x06 }, 0x00,0x01 }, -{{/*21*/ 'g', 'G', 0x07, 0x07, 'g', 'G', 0x07, 0x07 }, 0x00,0x01 }, -{{/*22*/ 'h', 'H', 0x08, 0x08, 'h', 'H', 0x08, 0x08 }, 0x00,0x01 }, -{{/*23*/ 'j', 'J', '\n', '\n', 'j', 'J', '\n', '\n' }, 0x00,0x01 }, -{{/*24*/ 'k', 'K', 0x0B, 0x0B, 'k', 'K', 0x0B, 0x0B }, 0x00,0x01 }, -{{/*25*/ 'l', 'L', 0x0C, 0x0C, 'l', 'L', 0x0C, 0x0C }, 0x00,0x01 }, -{{/*26*/ ';', '+', ';', ';', ';', ':', ';', ';' }, 0x00,0x00 }, -{{/*27*/ ':', '*', ':', ':', '\'', '\"', '\'', '\'' }, 0x00,0x00 }, -{{/*28*/ ']', '}', 0x1D, 0x1D, '`', '~', '~', '~' }, 0x00,0x00 }, -{{/*29*/ 'z', 'Z', 0x1A, 0x1A, 'z', 'Z', 0x1A, 0x1A }, 0x00,0x01 }, -{{/*2a*/ 'x', 'X', 0x18, 0x18, 'x', 'X', 0x18, 0x18 }, 0x00,0x01 }, -{{/*2b*/ 'c', 'C', 0x03, 0x03, 'c', 'C', 0x03, 0x03 }, 0x00,0x01 }, -{{/*2c*/ 'v', 'V', 0x16, 0x16, 'v', 'V', 0x16, 0x16 }, 0x00,0x01 }, -{{/*2d*/ 'b', 'B', 0x02, 0x02, 'b', 'B', 0x02, 0x02 }, 0x00,0x01 }, -{{/*2e*/ 'n', 'N', 0x0E, 0x0E, 'n', 'N', 0x0E, 0x0E }, 0x00,0x01 }, -{{/*2f*/ 'm', 'M', '\r', '\r', 'm', 'M', '\r', '\r' }, 0x00,0x01 }, -{{/*30*/ ',', '<', '<', '<', ',', '<', '<', '<' }, 0x00,0x00 }, -{{/*31*/ '.', '>', '>', '>', '.', '>', '>', '>' }, 0x00,0x00 }, -{{/*32*/ '/', '?', 0x7F, 0x7F, '/', '?', 0x7F, 0x7F }, 0x00,0x00 }, -{{/*33*/ NOP, '_', 0x1F, 0x1F, '\\', '|', 0x1C, 0x1C }, 0x80,0x00 }, -{{/*34*/ ' ', ' ', 0x00, 0x00, ' ', ' ', 0x00, 0x00 }, 0x00,0x00 }, -{{/*35*/ 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B }, 0x00,0x00 }, -{{/*36*/ F(59), F(59), F(59), F(59), F(59), F(59), F(59), F(59) }, 0xFF,0x00 }, -{{/*37*/ F(51), F(51), F(51), F(51), F(51), F(51), F(51), F(51) }, 0xFF,0x00 }, -{{/*38*/ F(60), F(60), F(60), F(60), F(60), F(60), F(60), F(60) }, 0xFF,0x00 }, -{{/*39*/ 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, RBT, RBT }, 0x03,0x02 }, -{{/*3a*/ F(50), F(50), F(50), F(50), F(50), F(50), F(50), F(50) }, 0xFF,0x00 }, -{{/*3b*/ F(53), F(53), F(53), F(53), F(53), F(53), F(53), F(53) }, 0xFF,0x00 }, -{{/*3c*/ F(55), F(55), F(55), F(55), F(55), F(55), F(55), F(55) }, 0xFF,0x00 }, -{{/*3d*/ F(58), F(58), F(58), F(58), F(58), F(58), F(58), F(58) }, 0xFF,0x00 }, -{{/*3e*/ F(49), F(49), F(49), F(49), F(49), F(49), F(49), F(49) }, 0xFF,0x00 }, -{{/*3f*/ F(57), F(57), F(57), F(57), F(57), F(57), F(57), F(57) }, 0xFF,0x00 }, -{{/*40*/ '-', '-', '-', '-', '-', '-', '-', '-' }, 0x00,0x00 }, -{{/*41*/ '/', '/', '/', '/', '/', '/', '/', '/' }, 0x00,0x00 }, -{{/*42*/ '7', '7', '7', '7', '7', '7', '7', '7' }, 0x00,0x00 }, -{{/*43*/ '8', '8', '8', '8', '8', '8', '8', '8' }, 0x00,0x00 }, -{{/*44*/ '9', '9', '9', '9', '9', '9', '9', '9' }, 0x00,0x00 }, -{{/*45*/ '*', '*', '*', '*', '*', '*', '*', '*' }, 0x00,0x00 }, -{{/*46*/ '4', '4', '4', '4', '4', '4', '4', '4' }, 0x00,0x00 }, -{{/*47*/ '5', '5', '5', '5', '5', '5', '5', '5' }, 0x00,0x00 }, -{{/*48*/ '6', '6', '6', '6', '6', '6', '6', '6' }, 0x00,0x00 }, -{{/*49*/ '+', '+', '+', '+', '+', '+', '+', '+' }, 0x00,0x00 }, -{{/*4a*/ '1', '1', '1', '1', '1', '1', '1', '1' }, 0x00,0x00 }, -{{/*4b*/ '2', '2', '2', '2', '2', '2', '2', '2' }, 0x00,0x00 }, -{{/*4c*/ '3', '3', '3', '3', '3', '3', '3', '3' }, 0x00,0x00 }, -{{/*4d*/ '=', '=', '=', '=', '=', '=', '=', '=' }, 0x00,0x00 }, -{{/*4e*/ '0', '0', '0', '0', '0', '0', '0', '0' }, 0x00,0x00 }, -{{/*4f*/ ',', ',', ',', ',', ',', ',', ',', ',' }, 0x00,0x00 }, -{{/*50*/ '.', '.', '.', '.', '.', '.', '.', '.' }, 0x00,0x00 }, -{{/*51*/ META, META, META, META, META, META, META, META }, 0xFF,0x00 }, -{{/*52*/ F(11), F(23), F(35), F(47), S(11), S(11), S(11), S(11) }, 0xFF,0x00 }, -{{/*53*/ F(12), F(24), F(36), F(48), S(12), S(12), S(12), S(12) }, 0xFF,0x00 }, -{{/*54*/ SLK, SLK, SLK, SLK, SLK, SLK, SLK, SLK }, 0xFF,0x00 }, -{{/*55*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*56*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*57*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*58*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*59*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*5a*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*5b*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*5c*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*5d*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*5e*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*5f*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*60*/ SLK, SPSC, SLK, SPSC, SUSP, NOP, SUSP, NOP }, 0xFF,0x00 }, -{{/*61*/ NEXT, NEXT, DBG, DBG, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*62*/ F( 1), F(13), F(25), F(37), S( 1), S( 1), S( 1), S( 1) }, 0xFF,0x00 }, -{{/*63*/ F( 2), F(14), F(26), F(38), S( 2), S( 2), S( 2), S( 2) }, 0xFF,0x00 }, -{{/*64*/ F( 3), F(15), F(27), F(39), S( 3), S( 3), S( 3), S( 3) }, 0xFF,0x00 }, -{{/*65*/ F( 4), F(16), F(28), F(40), S( 4), S( 4), S( 4), S( 4) }, 0xFF,0x00 }, -{{/*66*/ F( 5), F(17), F(29), F(41), S( 5), S( 5), S( 5), S( 5) }, 0xFF,0x00 }, -{{/*67*/ F( 6), F(18), F(30), F(42), S( 6), S( 6), S( 6), S( 6) }, 0xFF,0x00 }, -{{/*68*/ F( 7), F(19), F(31), F(43), S( 7), S( 7), S( 7), S( 7) }, 0xFF,0x00 }, -{{/*69*/ F( 8), F(20), F(32), F(44), S( 8), S( 8), S( 8), S( 8) }, 0xFF,0x00 }, -{{/*6a*/ F( 9), F(21), F(33), F(45), S( 9), S( 9), S( 9), S( 9) }, 0xFF,0x00 }, -{{/*6b*/ F(10), F(22), F(34), F(46), S(10), S(10), S(10), S(10) }, 0xFF,0x00 }, -{{/*6c*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*6d*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*6e*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*6f*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*70*/ LSH, LSH, LSH, LSH, LSH, LSH, LSH, LSH }, 0xFF,0x00 }, -{{/*71*/ CLK, CLK, CLK, CLK, CLK, CLK, CLK, CLK }, 0xFF,0x00 }, -{{/*72*/ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT }, 0xFF,0x00 }, -{{/*73*/ LALT, LALT, LALT, LALT, LALT, LALT, LALT, LALT }, 0xFF,0x00 }, -{{/*74*/ LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR, LCTR }, 0xFF,0x00 }, -{{/*75*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*76*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*77*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*78*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*79*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*7a*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*7b*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*7c*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*7d*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*7e*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -{{/*7f*/ NOP, NOP, NOP, NOP, NOP, NOP, NOP, NOP }, 0xFF,0x00 }, -} }; - -static accentmap_t accent_map = { 0, /* empty accent map */ - { - { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, - { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, - } -}; - -#endif /* !KBD_DFLT_KEYMAP */ - -static fkeytab_t fkey_tab[96] = { -/* 01-04 */ {"\033[M", 3}, {"\033[N", 3}, {"\033[O", 3}, {"\033[P", 3}, -/* 05-08 */ {"\033[Q", 3}, {"\033[R", 3}, {"\033[S", 3}, {"\033[T", 3}, -/* 09-12 */ {"\033[U", 3}, {"\033[V", 3}, {"\033[W", 3}, {"\033[X", 3}, -/* 13-16 */ {"\033[Y", 3}, {"\033[Z", 3}, {"\033[a", 3}, {"\033[b", 3}, -/* 17-20 */ {"\033[c", 3}, {"\033[d", 3}, {"\033[e", 3}, {"\033[f", 3}, -/* 21-24 */ {"\033[g", 3}, {"\033[h", 3}, {"\033[i", 3}, {"\033[j", 3}, -/* 25-28 */ {"\033[k", 3}, {"\033[l", 3}, {"\033[m", 3}, {"\033[n", 3}, -/* 29-32 */ {"\033[o", 3}, {"\033[p", 3}, {"\033[q", 3}, {"\033[r", 3}, -/* 33-36 */ {"\033[s", 3}, {"\033[t", 3}, {"\033[u", 3}, {"\033[v", 3}, -/* 37-40 */ {"\033[w", 3}, {"\033[x", 3}, {"\033[y", 3}, {"\033[z", 3}, -/* 41-44 */ {"\033[@", 3}, {"\033[[", 3}, {"\033[\\",3}, {"\033[]", 3}, -/* 45-48 */ {"\033[^", 3}, {"\033[_", 3}, {"\033[`", 3}, {"\033[{", 3}, -/* 49-52 */ {"\033[H", 3}, {"\033[A", 3}, {"\033[I", 3}, {"-" , 1}, -/* 53-56 */ {"\033[D", 3}, {"\033[E", 3}, {"\033[C", 3}, {"+" , 1}, -/* 57-60 */ {"\033[F", 3}, {"\033[B", 3}, {"\033[G", 3}, {"\033[L", 3}, -/* 61-64 */ {"\177", 1}, {"\033[J", 3}, {"\033[~", 3}, {"\033[}", 3}, -/* 65-68 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} , -/* 69-72 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} , -/* 73-76 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} , -/* 77-80 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} , -/* 81-84 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} , -/* 85-88 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} , -/* 89-92 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} , -/* 93-96 */ {"", 0} , {"", 0} , {"", 0} , {"", 0} -}; diff --git a/sys/pc98/cbus/pcrtc.c b/sys/pc98/cbus/pcrtc.c deleted file mode 100644 index 6fcbf57fbc63..000000000000 --- a/sys/pc98/cbus/pcrtc.c +++ /dev/null @@ -1,249 +0,0 @@ -/*- - * Copyright (c) 2008 TAKAHASHI Yoshihiro - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/clock.h> -#include <sys/kernel.h> -#include <sys/module.h> - -#include <pc98/cbus/cbus.h> -#include <isa/isavar.h> - -/* - * modified for PC98 by Kakefuda - */ - -/* - * RTC support routines - */ - -static void rtc_serialcombit(int); -static void rtc_serialcom(int); -static int rtc_inb(void); -static void rtc_outb(int); - -static void -rtc_serialcombit(int i) -{ - outb(IO_RTC, ((i&0x01)<<5)|0x07); - DELAY(1); - outb(IO_RTC, ((i&0x01)<<5)|0x17); - DELAY(1); - outb(IO_RTC, ((i&0x01)<<5)|0x07); - DELAY(1); -} - -static void -rtc_serialcom(int i) -{ - rtc_serialcombit(i&0x01); - rtc_serialcombit((i&0x02)>>1); - rtc_serialcombit((i&0x04)>>2); - rtc_serialcombit((i&0x08)>>3); - outb(IO_RTC, 0x07); - DELAY(1); - outb(IO_RTC, 0x0f); - DELAY(1); - outb(IO_RTC, 0x07); - DELAY(1); -} - -static void -rtc_outb(int val) -{ - int s; - int sa = 0; - - for (s=0;s<8;s++) { - sa = ((val >> s) & 0x01) ? 0x27 : 0x07; - outb(IO_RTC, sa); /* set DI & CLK 0 */ - DELAY(1); - outb(IO_RTC, sa | 0x10); /* CLK 1 */ - DELAY(1); - } - outb(IO_RTC, sa & 0xef); /* CLK 0 */ -} - -static int -rtc_inb(void) -{ - int s; - int sa = 0; - - for (s=0;s<8;s++) { - sa |= ((inb(0x33) & 0x01) << s); - outb(IO_RTC, 0x17); /* CLK 1 */ - DELAY(1); - outb(IO_RTC, 0x07); /* CLK 0 */ - DELAY(2); - } - return sa; -} - -/********************************************************************** - * RTC driver for subr_rtc - */ - -#include "clock_if.h" - -#include <sys/rman.h> - -struct pcrtc_softc { - int port_rid1, port_rid2; - struct resource *port_res1, *port_res2; -}; - -/* - * Attach to the ISA PnP descriptors for the timer and realtime clock. - */ -static struct isa_pnp_id pcrtc_ids[] = { - { 0x000bd041 /* PNP0B00 */, "AT realtime clock" }, - { 0 } -}; - -static int -pcrtc_probe(device_t dev) -{ - int result; - - device_set_desc(dev, "PC Real Time Clock"); - result = ISA_PNP_PROBE(device_get_parent(dev), dev, pcrtc_ids); - /* ENXIO if wrong PnP-ID, ENOENT ifno PnP-ID, zero if good PnP-iD */ - if (result != ENOENT) - return(result); - /* All PC's have an RTC, and we're hosed without it, so... */ - return (BUS_PROBE_LOW_PRIORITY); -} - -static int -pcrtc_attach(device_t dev) -{ - struct pcrtc_softc *sc; - - /* - * Not that we need them or anything, but grab our resources - * so they show up, correctly attributed, in the big picture. - */ - sc = device_get_softc(dev); - sc->port_rid1 = 0; - bus_set_resource(dev, SYS_RES_IOPORT, sc->port_rid1, IO_RTC, 1); - if (!(sc->port_res1 = bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->port_rid1, IO_RTC, IO_RTC, 1, RF_ACTIVE))) - device_printf(dev, "Warning: Couldn't map I/O.\n"); - sc->port_rid2 = 1; - bus_set_resource(dev, SYS_RES_IOPORT, sc->port_rid2, 0x33, 1); - if (!(sc->port_res2 = bus_alloc_resource(dev, SYS_RES_IOPORT, - &sc->port_rid2, 0x33, 0x33, 1, RF_ACTIVE))) - device_printf(dev, "Warning: Couldn't map I/O.\n"); - - clock_register(dev, 1000000); - return(0); -} - -static int -pcrtc_settime(device_t dev __unused, struct timespec *ts) -{ - struct clocktime ct; - - clock_ts_to_ct(ts, &ct); - - rtc_serialcom(0x01); /* Register shift command. */ - - rtc_outb(bin2bcd(ct.sec)); /* Write back Seconds */ - rtc_outb(bin2bcd(ct.min)); /* Write back Minutes */ - rtc_outb(bin2bcd(ct.hour)); /* Write back Hours */ - - rtc_outb(bin2bcd(ct.day)); /* Write back Day */ - rtc_outb((ct.mon << 4) | ct.dow); /* Write back Month and DOW */ - rtc_outb(bin2bcd(ct.year % 100)); /* Write back Year */ - - rtc_serialcom(0x02); /* Time set & Counter hold command. */ - rtc_serialcom(0x00); /* Register hold command. */ - - return (0); -} - -static int -pcrtc_gettime(device_t dev, struct timespec *ts) -{ - struct clocktime ct; - int i; - - rtc_serialcom(0x03); /* Time Read */ - rtc_serialcom(0x01); /* Register shift command. */ - DELAY(20); - - ct.nsec = 0; - ct.sec = bcd2bin(rtc_inb() & 0xff); /* sec */ - ct.min = bcd2bin(rtc_inb() & 0xff); /* min */ - ct.hour = bcd2bin(rtc_inb() & 0xff); /* hour */ - ct.day = bcd2bin(rtc_inb() & 0xff); /* date */ - i = rtc_inb(); - ct.dow = i & 0x0f; /* dow */ - ct.mon = (i >> 4) & 0x0f; /* month */ - ct.year = bcd2bin(rtc_inb() & 0xff) + 1900; /* year */ - if (ct.year < 1995) - ct.year += 100; - - /* Set dow = -1 because some clocks don't set it correctly. */ - ct.dow = -1; - - return (clock_ct_to_ts(&ct, ts)); -} - -static device_method_t pcrtc_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pcrtc_probe), - DEVMETHOD(device_attach, pcrtc_attach), - DEVMETHOD(device_detach, bus_generic_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - /* XXX stop statclock? */ - DEVMETHOD(device_resume, bus_generic_resume), - /* XXX restart statclock? */ - - /* clock interface */ - DEVMETHOD(clock_gettime, pcrtc_gettime), - DEVMETHOD(clock_settime, pcrtc_settime), - - { 0, 0 } -}; - -static driver_t pcrtc_driver = { - "pcrtc", - pcrtc_methods, - sizeof(struct pcrtc_softc), -}; - -static devclass_t pcrtc_devclass; - -DRIVER_MODULE(pcrtc, isa, pcrtc_driver, pcrtc_devclass, 0, 0); diff --git a/sys/pc98/cbus/pmc.c b/sys/pc98/cbus/pmc.c deleted file mode 100644 index ad59767c1f3f..000000000000 --- a/sys/pc98/cbus/pmc.c +++ /dev/null @@ -1,244 +0,0 @@ -/*- - * PMC (Power Management Controller of NEC PC-98Note) Driver - * - * Copyright (c) 2001 Chiharu Shibata. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/eventhandler.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/types.h> -#include <sys/conf.h> -#include <sys/reboot.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <isa/isavar.h> - -struct pmc_isa_softc { - struct resource *port_res; - eventhandler_tag evt; - int flags; -}; - -static int pmc_isa_alloc_resources(device_t); -static void pmc_isa_release_resources(device_t); -static int pmc_isa_probe(device_t); -static int pmc_isa_attach(device_t); -static int pmc_isa_detach(device_t); - -#define PMC_ISA_PORT 0x8f0 -#define PMC_ISA_PORTSIZE 4 - -#define sc_inw(sc, port) \ - bus_space_read_2(rman_get_bustag((sc)->port_res), \ - rman_get_bushandle((sc)->port_res), (port)) - -#define sc_outw(sc, port, value) \ - bus_space_write_2(rman_get_bustag((sc)->port_res), \ - rman_get_bushandle((sc)->port_res), (port), (value)) - -static void -pmc_poweroff(void *arg, int howto) -{ - struct pmc_isa_softc *sc = (struct pmc_isa_softc *)arg; - - if (!sc->flags) { - outb(0x5e8e, inb(0x5e8e) & ~0x11); /* FDD LED off */ - } - - if (!(howto & RB_POWEROFF)) { - return; - } - - sc_outw(sc, 0, 0x0044); - sc_outw(sc, 2, 1 << 10); -#if 1 - /* for 9801NS/T */ - sc_outw(sc, 0, 0xf00a); - sc_outw(sc, 2, 1 << 9); -#endif -} - -static int -pmc_isa_alloc_resources(device_t dev) -{ - struct pmc_isa_softc *sc = device_get_softc(dev); - int rid; - - bzero(sc, sizeof(*sc)); - - rid = 0; - sc->port_res = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, - PMC_ISA_PORTSIZE, RF_ACTIVE); - if (sc->port_res == NULL) { - return (ENOMEM); - } - - return 0; -} - -static void -pmc_isa_release_resources(device_t dev) -{ - struct pmc_isa_softc *sc = device_get_softc(dev); - - if (sc->port_res != NULL) { - bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->port_res); - } - sc->port_res = NULL; -} - -static int -pmc_isa_probe(device_t dev) -{ - struct pmc_isa_softc *sc = device_get_softc(dev); - u_int port; - u_int16_t save, tmp; - -#if 0 - if (isa_get_vendorid(dev)) { - return ENXIO; - } - if (device_get_unit(dev) > 0) { - printf("pmc: Only one PMC driver supported.\n"); - return ENXIO; - } -#endif - port = isa_get_port(dev); - if (port == -1) { - port = PMC_ISA_PORT; - } - if (bootverbose) { - device_printf(dev, "port = 0x%x\n", port); - } - - if (bus_set_resource(dev, SYS_RES_IOPORT, 0, port, PMC_ISA_PORTSIZE)) { - if (bootverbose) { - device_printf(dev, "bus_set_resource failed\n"); - } - return ENXIO; - } - if (pmc_isa_alloc_resources(dev)) { - if (bootverbose) { - device_printf(dev, "pmc_isa_alloc_resources failed\n"); - } - return ENXIO; - } - - /* Check the existence of PMC */ - sc_outw(sc, 0, 0x0052); - save = sc_inw(sc, 2); - tmp = save & ~0x3f; - sc_outw(sc, 2, tmp); - if (sc_inw(sc, 2) != tmp) { - if (bootverbose) { - device_printf(dev, "failed to clear index(0x0052)\n"); - } - - pmc_isa_release_resources(dev); - return ENXIO; - } - - tmp |= 0x3e; - sc_outw(sc, 2, tmp); - if (sc_inw(sc, 2) != tmp) { - if (bootverbose) { - device_printf(dev, "failed to set index(0x0052)\n"); - } - - pmc_isa_release_resources(dev); - return ENXIO; - } - sc_outw(sc, 2, save); - - pmc_isa_release_resources(dev); - - device_set_desc(dev, "Power Management Controller"); - return 0; -} - -static int -pmc_isa_attach(device_t dev) -{ - struct pmc_isa_softc *sc = device_get_softc(dev); - int error; - - error = pmc_isa_alloc_resources(dev); - if (error) { - device_printf(dev, "resource allocation failed\n"); - return error; - } - - /* Power the system off using PMC */ - sc->evt = EVENTHANDLER_REGISTER(shutdown_final, pmc_poweroff, sc, - SHUTDOWN_PRI_LAST); - sc->flags = device_get_flags(dev); - return 0; -} - -static int -pmc_isa_detach(device_t dev) -{ - struct pmc_isa_softc *sc = device_get_softc(dev); - - if (bootverbose) { - device_printf(dev, "pmc_isa_detach called\n"); - } - - if (sc->evt != NULL) { - EVENTHANDLER_DEREGISTER(shutdown_final, sc->evt); - } - sc->evt = NULL; - - pmc_isa_release_resources(dev); - return 0; -} - -static device_method_t pmc_isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pmc_isa_probe), - DEVMETHOD(device_attach, pmc_isa_attach), - DEVMETHOD(device_detach, pmc_isa_detach), - {0, 0} -}; - -static driver_t pmc_isa_driver = { - "pmc", - pmc_isa_methods, sizeof(struct pmc_isa_softc), -}; - -devclass_t pmc_devclass; - -DRIVER_MODULE(pmc, isa, pmc_isa_driver, pmc_devclass, 0, 0); diff --git a/sys/pc98/cbus/sc_machdep.h b/sys/pc98/cbus/sc_machdep.h deleted file mode 100644 index 5dbc94eb182c..000000000000 --- a/sys/pc98/cbus/sc_machdep.h +++ /dev/null @@ -1,52 +0,0 @@ -/*- - * Copyright (c) 1999 FreeBSD(98) Porting 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. - * - * $FreeBSD$ - */ - -#ifndef _PC98_PC98_SC_MACHDEP_H_ -#define _PC98_PC98_SC_MACHDEP_H_ - -#undef SC_DFLT_FONT -#undef SC_MOUSE_CHAR -#undef SC_PIXEL_MODE -#undef SC_NO_FONT_LOADING -#define SC_NO_FONT_LOADING 1 -#undef SC_NO_PALETTE_LOADING -#define SC_NO_PALETTE_LOADING 1 - -#ifndef SC_KERNEL_CONS_ATTR -#define SC_KERNEL_CONS_ATTR (FG_LIGHTGREY | BG_BLACK) -#endif - -#define KANJI 1 - -#define UJIS 0 -#define SJIS 1 - -#define PRINTABLE(c) ((c) > 0x1b || ((c) > 0x0f && (c) < 0x1b) \ - || (c) < 0x07) - -#endif /* !_PC98_PC98_SC_MACHDEP_H_ */ diff --git a/sys/pc98/cbus/scgdcrndr.c b/sys/pc98/cbus/scgdcrndr.c deleted file mode 100644 index 53ff41ebc300..000000000000 --- a/sys/pc98/cbus/scgdcrndr.c +++ /dev/null @@ -1,208 +0,0 @@ -/*- - * Copyright (c) 1999 FreeBSD(98) Porting 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. - * - * $FreeBSD$ - */ - -#include "opt_syscons.h" -#include "opt_gdc.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/fbio.h> -#include <sys/consio.h> - -#include <dev/fb/fbreg.h> -#include <dev/syscons/syscons.h> - -#ifndef SC_RENDER_DEBUG -#define SC_RENDER_DEBUG 0 -#endif - -static vr_clear_t gdc_txtclear; -static vr_draw_border_t gdc_txtborder; -static vr_draw_t gdc_txtdraw; -static vr_set_cursor_t gdc_txtcursor_shape; -static vr_draw_cursor_t gdc_txtcursor; -#ifndef SC_NO_CUTPASTE -static vr_draw_mouse_t gdc_txtmouse; -#else -#define gdc_txtmouse (vr_draw_mouse_t *)gdc_nop -#endif - -#ifndef SC_NO_MODE_CHANGE -static vr_draw_border_t gdc_grborder; -#endif - -static void gdc_nop(scr_stat *scp, ...); - -static sc_rndr_sw_t txtrndrsw = { - (vr_init_t *)gdc_nop, - gdc_txtclear, - gdc_txtborder, - gdc_txtdraw, - gdc_txtcursor_shape, - gdc_txtcursor, - (vr_blink_cursor_t *)gdc_nop, - (vr_set_mouse_t *)gdc_nop, - gdc_txtmouse, -}; -RENDERER(gdc, 0, txtrndrsw, gdc_set); - -#ifndef SC_NO_MODE_CHANGE -static sc_rndr_sw_t grrndrsw = { - (vr_init_t *)gdc_nop, - (vr_clear_t *)gdc_nop, - gdc_grborder, - (vr_draw_t *)gdc_nop, - (vr_set_cursor_t *)gdc_nop, - (vr_draw_cursor_t *)gdc_nop, - (vr_blink_cursor_t *)gdc_nop, - (vr_set_mouse_t *)gdc_nop, - (vr_draw_mouse_t *)gdc_nop, -}; -RENDERER(gdc, GRAPHICS_MODE, grrndrsw, gdc_set); -#endif /* SC_NO_MODE_CHANGE */ - -RENDERER_MODULE(gdc, gdc_set); - -static void -gdc_nop(scr_stat *scp, ...) -{ -} - -/* text mode renderer */ - -static void -gdc_txtclear(scr_stat *scp, int c, int attr) -{ - sc_vtb_clear(&scp->scr, c, attr); -} - -static void -gdc_txtborder(scr_stat *scp, int color) -{ - vidd_set_border(scp->sc->adp, color); -} - -static void -gdc_txtdraw(scr_stat *scp, int from, int count, int flip) -{ - vm_offset_t p; - int c; - int a; - - if (from + count > scp->xsize*scp->ysize) - count = scp->xsize*scp->ysize - from; - - if (flip) { - for (p = sc_vtb_pointer(&scp->scr, from); count-- > 0; ++from) { - c = sc_vtb_getc(&scp->vtb, from); - a = sc_vtb_geta(&scp->vtb, from); -#if 0 - a ^= 0x0800; -#else - a = (a & 0x8800) | ((a & 0x7000) >> 4) - | ((a & 0x0700) << 4); -#endif - p = sc_vtb_putchar(&scp->scr, p, c, a); - } - } else { - sc_vtb_copy(&scp->vtb, from, &scp->scr, from, count); - } -} - -static void -gdc_txtcursor_shape(scr_stat *scp, int base, int height, int blink) -{ - if (base < 0 || base >= scp->font_size) - return; - /* the caller may set height <= 0 in order to disable the cursor */ - vidd_set_hw_cursor_shape(scp->sc->adp, base, height, scp->font_size, - blink); -} - -static void -gdc_txtcursor(scr_stat *scp, int at, int blink, int on, int flip) -{ - if (on) { - scp->status |= VR_CURSOR_ON; - vidd_set_hw_cursor(scp->sc->adp, at%scp->xsize, - at/scp->xsize); - } else { - if (scp->status & VR_CURSOR_ON) - vidd_set_hw_cursor(scp->sc->adp, -1, -1); - scp->status &= ~VR_CURSOR_ON; - } -} - -#ifndef SC_NO_CUTPASTE - -static void -draw_txtmouse(scr_stat *scp, int x, int y) -{ - int at; - int a; - - at = (y/scp->font_size - scp->yoff)*scp->xsize + x/8 - scp->xoff; - a = sc_vtb_geta(&scp->vtb, at); -#if 0 - a ^= 0x0800; -#else - a = (a & 0x8800) | ((a & 0x7000) >> 4) - | ((a & 0x0700) << 4); -#endif - sc_vtb_putc(&scp->scr, at, sc_vtb_getc(&scp->scr, at), a); -} - -static void -remove_txtmouse(scr_stat *scp, int x, int y) -{ -} - -static void -gdc_txtmouse(scr_stat *scp, int x, int y, int on) -{ - if (on) - draw_txtmouse(scp, x, y); - else - remove_txtmouse(scp, x, y); -} - -#endif /* SC_NO_CUTPASTE */ - -#ifndef SC_NO_MODE_CHANGE - -/* graphics mode renderer */ - -static void -gdc_grborder(scr_stat *scp, int color) -{ - vidd_set_border(scp->sc->adp, color); -} - -#endif /* SC_NO_MODE_CHANGE */ diff --git a/sys/pc98/cbus/scterm-sck.c b/sys/pc98/cbus/scterm-sck.c deleted file mode 100644 index a7615d6f5886..000000000000 --- a/sys/pc98/cbus/scterm-sck.c +++ /dev/null @@ -1,1229 +0,0 @@ -/*- - * Copyright (c) 1999 FreeBSD(98) Porting 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. - * - * $FreeBSD$ - */ - -#include "opt_syscons.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/consio.h> - -#include <machine/pc/display.h> - -#include <dev/syscons/syscons.h> -#include <pc98/cbus/sctermvar.h> - -#define MAX_ESC_PAR 5 - -#ifdef KANJI -#define IS_KTYPE_ASCII_or_HANKAKU(A) (!((A) & 0xee)) -#define IS_KTYPE_KANA(A) ((A) & 0x11) -#define KTYPE_MASK_CTRL(A) ((A) &= 0xF0) -#endif /* KANJI */ - -/* attribute flags */ -typedef struct { - u_short fg; /* foreground color */ - u_short bg; /* background color */ -} color_t; - -typedef struct { - int flags; -#define SCTERM_BUSY (1 << 0) - int esc; - int num_param; - int last_param; - int param[MAX_ESC_PAR]; - int saved_xpos; - int saved_ypos; - -#ifdef KANJI - u_char kanji_1st_char; - u_char kanji_type; -#define KTYPE_ASCII 0 /* ASCII */ -#define KTYPE_KANA 1 /* HANKAKU */ -#define KTYPE_JKANA 0x10 /* JIS HANKAKU */ -#define KTYPE_7JIS 0x20 /* JIS */ -#define KTYPE_SJIS 2 /* Shift JIS */ -#define KTYPE_UJIS 4 /* UJIS */ -#define KTYPE_SUKANA 3 /* Shift JIS or UJIS HANKAKU */ -#define KTYPE_SUJIS 6 /* SHift JIS or UJIS */ -#define KTYPE_KANIN 0x80 /* Kanji Invoke sequence */ -#define KTYPE_ASCIN 0x40 /* ASCII Invoke sequence */ -#endif /* KANJI */ - - int attr_mask; /* current logical attr mask */ -#define NORMAL_ATTR 0x00 -#define BLINK_ATTR 0x01 -#define BOLD_ATTR 0x02 -#define UNDERLINE_ATTR 0x04 -#define REVERSE_ATTR 0x08 -#define FG_CHANGED 0x10 -#define BG_CHANGED 0x20 - int cur_attr; /* current hardware attr word */ - color_t cur_color; /* current hardware color */ - color_t std_color; /* normal hardware color */ - color_t rev_color; /* reverse hardware color */ - color_t dflt_std_color; /* default normal color */ - color_t dflt_rev_color; /* default reverse color */ -} term_stat; - -static sc_term_init_t scterm_init; -static sc_term_term_t scterm_term; -static sc_term_puts_t scterm_puts; -static sc_term_ioctl_t scterm_ioctl; -static sc_term_reset_t scterm_reset; -static sc_term_default_attr_t scterm_default_attr; -static sc_term_clear_t scterm_clear; -static sc_term_notify_t scterm_notify; -static sc_term_input_t scterm_input; -static sc_term_fkeystr_t scterm_fkeystr; - -static sc_term_sw_t sc_term_sc = { - { NULL, NULL }, - "sck", /* emulator name */ - "syscons kanji terminal", /* description */ - "*", /* matching renderer, any :-) */ - sizeof(term_stat), /* softc size */ - 0, - scterm_init, - scterm_term, - scterm_puts, - scterm_ioctl, - scterm_reset, - scterm_default_attr, - scterm_clear, - scterm_notify, - scterm_input, - scterm_fkeystr, -}; - -SCTERM_MODULE(sc, sc_term_sc); - -static term_stat reserved_term_stat; -static int default_kanji = UJIS; -static void scterm_scan_esc(scr_stat *scp, term_stat *tcp, - u_char c); -static int mask2attr(term_stat *tcp); - -#ifdef KANJI -static inline u_char -iskanji1(u_char mode, u_char c) -{ - if (c > 0x80) { - if ((c >= 0xa1) && (c <= 0xdf)) { - if (default_kanji == UJIS) { - /* UJIS */ - return KTYPE_UJIS; - } - if (default_kanji == SJIS) { - /* SJIS HANKAKU */ - return KTYPE_KANA; - } - } - - if (c <= 0x9f) { - if (c == 0x8e) { - /* SJIS or UJIS HANKAKU */ - return KTYPE_SUKANA; - } - - /* SJIS */ - default_kanji = SJIS; - return KTYPE_SJIS; - } - - if ((c >= 0xe0) && (c <= 0xef)) { - /* SJIS or UJIS */ - return KTYPE_SUJIS; - } - - if ((c >= 0xf0) && (c <= 0xfe)) { - /* UJIS */ - default_kanji = UJIS; - return KTYPE_UJIS; - } - } else { - if ((mode == KTYPE_7JIS) && (c >= 0x21) && (c <= 0x7e)) { - /* JIS */ - default_kanji = UJIS; - return KTYPE_7JIS; - } - - if ((mode == KTYPE_JKANA) && (c >= 0x21) && (c <= 0x5f)) { - /* JIS HANKAKU */ - default_kanji = UJIS; - return KTYPE_JKANA; - } - } - - return KTYPE_ASCII; -} - -static inline u_char -iskanji2(u_char mode, u_char c) -{ - switch (mode) { - case KTYPE_7JIS: - if ((c >= 0x21) && (c <= 0x7e)) { - /* JIS */ - return KTYPE_7JIS; - } - break; - case KTYPE_SJIS: - if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { - /* SJIS */ - return KTYPE_SJIS; - } - break; - case KTYPE_UJIS: - if ((c >= 0xa1) && (c <= 0xfe)) { - /* UJIS */ - return KTYPE_UJIS; - } - break; - case KTYPE_SUKANA: - if ((c >= 0xa1) && (c <= 0xdf) && (default_kanji == UJIS)) { - /* UJIS HANKAKU */ - return KTYPE_KANA; - } - if ((c >= 0x40) && (c <= 0xfc) && (c != 0x7f)) { - /* SJIS */ - default_kanji = SJIS; - return KTYPE_SJIS; - } - break; - case KTYPE_SUJIS: - if ((c >= 0x40) && (c <= 0xa0) && (c != 0x7f)) { - /* SJIS */ - default_kanji = SJIS; - return KTYPE_SJIS; - } - if ((c == 0xfd) || (c == 0xfe)) { - /* UJIS */ - default_kanji = UJIS; - return KTYPE_UJIS; - } - if ((c >= 0xa1) && (c <= 0xfc)) { - if (default_kanji == SJIS) - return KTYPE_SJIS; - if (default_kanji == UJIS) - return KTYPE_UJIS; - } - break; - } - - return KTYPE_ASCII; -} - -/* - * JIS X0208-83 keisen conversion table - */ -static u_short keiConv[32] = { - 0x240c, 0x260c, 0x300c, 0x340c, 0x3c0c, 0x380c, 0x400c, 0x500c, - 0x480c, 0x580c, 0x600c, 0x250c, 0x270c, 0x330c, 0x370c, 0x3f0c, - 0x3b0c, 0x470c, 0x570c, 0x4f0c, 0x5f0c, 0x6f0c, 0x440c, 0x530c, - 0x4c0c, 0x5b0c, 0x630c, 0x410c, 0x540c, 0x490c, 0x5c0c, 0x660c -}; - -static u_short -kanji_convert(u_char mode, u_char h, u_char l) -{ - u_short tmp, high, low, c; - - high = (u_short) h; - low = (u_short) l; - - switch (mode) { - case KTYPE_SJIS: /* SHIFT JIS */ - if (low >= 0xe0) { - low -= 0x40; - } - low = (low - 0x81) * 2 + 0x21; - if (high > 0x7f) { - high--; - } - if (high > 0x9d) { - low++; - high -= 0x9e - 0x21; - } else { - high -= 0x40 - 0x21; - } - high &= 0x7F; - low &= 0x7F; - tmp = ((high << 8) | low) - 0x20; - break; - case KTYPE_7JIS: /* JIS */ - case KTYPE_UJIS: /* UJIS */ - high &= 0x7F; - low &= 0x7F; - tmp = ((high << 8) | low) - 0x20; - break; - default: - tmp = 0; - break; - } - - /* keisen */ - c = ((tmp & 0xff) << 8) | (tmp >> 8); - /* 0x2821 .. 0x2840 */ - if (0x0821 <= c && c <= 0x0840) - tmp = keiConv[c - 0x0821]; - - return (tmp); -} -#endif /* KANJI */ - -static int -scterm_init(scr_stat *scp, void **softc, int code) -{ - term_stat *tcp; - - if (*softc == NULL) { - if (reserved_term_stat.flags & SCTERM_BUSY) - return EINVAL; - *softc = &reserved_term_stat; - } - tcp = *softc; - - switch (code) { - case SC_TE_COLD_INIT: - bzero(tcp, sizeof(*tcp)); - tcp->flags = SCTERM_BUSY; - tcp->esc = 0; - tcp->saved_xpos = -1; - tcp->saved_ypos = -1; -#ifdef KANJI - tcp->kanji_1st_char = 0; - tcp->kanji_type = KTYPE_ASCII; -#endif - tcp->attr_mask = NORMAL_ATTR; - /* XXX */ - tcp->dflt_std_color.fg = SC_NORM_ATTR & 0x0f; - tcp->dflt_std_color.bg = (SC_NORM_ATTR >> 4) & 0x0f; - tcp->dflt_rev_color.fg = SC_NORM_REV_ATTR & 0x0f; - tcp->dflt_rev_color.bg = (SC_NORM_REV_ATTR >> 4) & 0x0f; - tcp->std_color = tcp->dflt_std_color; - tcp->rev_color = tcp->dflt_rev_color; - tcp->cur_color = tcp->std_color; - tcp->cur_attr = mask2attr(tcp); - ++sc_term_sc.te_refcount; - break; - - case SC_TE_WARM_INIT: - tcp->esc = 0; - tcp->saved_xpos = -1; - tcp->saved_ypos = -1; -#if 0 - tcp->std_color = tcp->dflt_std_color; - tcp->rev_color = tcp->dflt_rev_color; -#endif - tcp->cur_color = tcp->std_color; - tcp->cur_attr = mask2attr(tcp); - break; - } - - return 0; -} - -static int -scterm_term(scr_stat *scp, void **softc) -{ - if (*softc == &reserved_term_stat) { - *softc = NULL; - bzero(&reserved_term_stat, sizeof(reserved_term_stat)); - } - --sc_term_sc.te_refcount; - return 0; -} - -static void -scterm_scan_esc(scr_stat *scp, term_stat *tcp, u_char c) -{ - static u_char ansi_col[16] = { - FG_BLACK, FG_RED, FG_GREEN, FG_BROWN, - FG_BLUE, FG_MAGENTA, FG_CYAN, FG_LIGHTGREY, - FG_DARKGREY, FG_LIGHTRED, FG_LIGHTGREEN, FG_YELLOW, - FG_LIGHTBLUE, FG_LIGHTMAGENTA, FG_LIGHTCYAN, FG_WHITE - }; - static int cattrs[] = { - 0, /* block */ - CONS_BLINK_CURSOR, /* blinking block */ - CONS_CHAR_CURSOR, /* underline */ - CONS_CHAR_CURSOR | CONS_BLINK_CURSOR, /* blinking underline */ - CONS_RESET_CURSOR, /* reset to default */ - CONS_HIDDEN_CURSOR, /* hide cursor */ - }; - static int tcattrs[] = { - CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, /* normal */ - CONS_HIDDEN_CURSOR | CONS_LOCAL_CURSOR, /* invisible */ - CONS_BLINK_CURSOR | CONS_LOCAL_CURSOR, /* very visible */ - }; - sc_softc_t *sc; - int v0, v1, v2; - int i, n; - - i = n = 0; - sc = scp->sc; - if (tcp->esc == 1) { /* seen ESC */ -#ifdef KANJI - switch (tcp->kanji_type) { - case KTYPE_KANIN: /* Kanji Invoke sequence */ - switch (c) { - case 'B': - case '@': - tcp->kanji_type = KTYPE_7JIS; - tcp->esc = 0; - tcp->kanji_1st_char = 0; - return; - default: - tcp->kanji_type = KTYPE_ASCII; - tcp->esc = 0; - break; - } - break; - case KTYPE_ASCIN: /* Ascii Invoke sequence */ - switch (c) { - case 'J': - case 'B': - case 'H': - tcp->kanji_type = KTYPE_ASCII; - tcp->esc = 0; - tcp->kanji_1st_char = 0; - return; - case 'I': - tcp->kanji_type = KTYPE_JKANA; - tcp->esc = 0; - tcp->kanji_1st_char = 0; - return; - default: - tcp->kanji_type = KTYPE_ASCII; - tcp->esc = 0; - break; - } - break; - default: - break; - } -#endif - switch (c) { - - case '7': /* Save cursor position */ - tcp->saved_xpos = scp->xpos; - tcp->saved_ypos = scp->ypos; - break; - - case '8': /* Restore saved cursor position */ - if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) - sc_move_cursor(scp, tcp->saved_xpos, - tcp->saved_ypos); - break; - - case '[': /* Start ESC [ sequence */ - tcp->esc = 2; - tcp->last_param = -1; - for (i = tcp->num_param; i < MAX_ESC_PAR; i++) - tcp->param[i] = 1; - tcp->num_param = 0; - return; - -#ifdef KANJI - case '$': /* Kanji Invoke sequence */ - tcp->kanji_type = KTYPE_KANIN; - return; -#endif - - case 'M': /* Move cursor up 1 line, scroll if at top */ - sc_term_up_scroll(scp, 1, sc->scr_map[0x20], - tcp->cur_attr, 0, 0); - break; -#ifdef notyet - case 'Q': - tcp->esc = 4; - return; -#endif - case 'c': /* reset */ - tcp->attr_mask = NORMAL_ATTR; - tcp->cur_color = tcp->std_color - = tcp->dflt_std_color; - tcp->rev_color = tcp->dflt_rev_color; - tcp->cur_attr = mask2attr(tcp); - sc_change_cursor_shape(scp, - CONS_RESET_CURSOR | CONS_LOCAL_CURSOR, -1, -1); - sc_clear_screen(scp); - break; - - case '(': /* iso-2022: designate 94 character set to G0 */ -#ifdef KANJI - tcp->kanji_type = KTYPE_ASCIN; -#else - tcp->esc = 5; -#endif - return; - } - } else if (tcp->esc == 2) { /* seen ESC [ */ - if (c >= '0' && c <= '9') { - if (tcp->num_param < MAX_ESC_PAR) { - if (tcp->last_param != tcp->num_param) { - tcp->last_param = tcp->num_param; - tcp->param[tcp->num_param] = 0; - } else { - tcp->param[tcp->num_param] *= 10; - } - tcp->param[tcp->num_param] += c - '0'; - return; - } - } - tcp->num_param = tcp->last_param + 1; - switch (c) { - - case ';': - if (tcp->num_param < MAX_ESC_PAR) - return; - break; - - case '=': - tcp->esc = 3; - tcp->last_param = -1; - for (i = tcp->num_param; i < MAX_ESC_PAR; i++) - tcp->param[i] = 1; - tcp->num_param = 0; - return; - - case 'A': /* up n rows */ - sc_term_up(scp, tcp->param[0], 0); - break; - - case 'B': /* down n rows */ - sc_term_down(scp, tcp->param[0], 0); - break; - - case 'C': /* right n columns */ - sc_term_right(scp, tcp->param[0]); - break; - - case 'D': /* left n columns */ - sc_term_left(scp, tcp->param[0]); - break; - - case 'E': /* cursor to start of line n lines down */ - n = tcp->param[0]; - if (n < 1) - n = 1; - sc_move_cursor(scp, 0, scp->ypos + n); - break; - - case 'F': /* cursor to start of line n lines up */ - n = tcp->param[0]; - if (n < 1) - n = 1; - sc_move_cursor(scp, 0, scp->ypos - n); - break; - - case 'f': /* Cursor move */ - case 'H': - if (tcp->num_param == 0) - sc_move_cursor(scp, 0, 0); - else if (tcp->num_param == 2) - sc_move_cursor(scp, tcp->param[1] - 1, - tcp->param[0] - 1); - break; - - case 'J': /* Clear all or part of display */ - if (tcp->num_param == 0) - n = 0; - else - n = tcp->param[0]; - sc_term_clr_eos(scp, n, sc->scr_map[0x20], - tcp->cur_attr); - break; - - case 'K': /* Clear all or part of line */ - if (tcp->num_param == 0) - n = 0; - else - n = tcp->param[0]; - sc_term_clr_eol(scp, n, sc->scr_map[0x20], - tcp->cur_attr); - break; - - case 'L': /* Insert n lines */ - sc_term_ins_line(scp, scp->ypos, tcp->param[0], - sc->scr_map[0x20], tcp->cur_attr, 0); - break; - - case 'M': /* Delete n lines */ - sc_term_del_line(scp, scp->ypos, tcp->param[0], - sc->scr_map[0x20], tcp->cur_attr, 0); - break; - - case 'P': /* Delete n chars */ - sc_term_del_char(scp, tcp->param[0], - sc->scr_map[0x20], tcp->cur_attr); - break; - - case '@': /* Insert n chars */ - sc_term_ins_char(scp, tcp->param[0], - sc->scr_map[0x20], tcp->cur_attr); - break; - - case 'S': /* scroll up n lines */ - sc_term_del_line(scp, 0, tcp->param[0], - sc->scr_map[0x20], tcp->cur_attr, 0); - break; - - case 'T': /* scroll down n lines */ - sc_term_ins_line(scp, 0, tcp->param[0], - sc->scr_map[0x20], tcp->cur_attr, 0); - break; - - case 'X': /* erase n characters in line */ - n = tcp->param[0]; - if (n < 1) - n = 1; - if (n > scp->xsize - scp->xpos) - n = scp->xsize - scp->xpos; - sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, - sc->scr_map[0x20], tcp->cur_attr); - mark_for_update(scp, scp->cursor_pos); - mark_for_update(scp, scp->cursor_pos + n - 1); - break; - - case 'Z': /* move n tabs backwards */ - sc_term_backtab(scp, tcp->param[0]); - break; - - case '`': /* move cursor to column n */ - sc_term_col(scp, tcp->param[0]); - break; - - case 'a': /* move cursor n columns to the right */ - sc_term_right(scp, tcp->param[0]); - break; - - case 'd': /* move cursor to row n */ - sc_term_row(scp, tcp->param[0]); - break; - - case 'e': /* move cursor n rows down */ - sc_term_down(scp, tcp->param[0], 0); - break; - - case 'm': /* change attribute */ - if (tcp->num_param == 0) { - tcp->attr_mask = NORMAL_ATTR; - tcp->cur_color = tcp->std_color; - tcp->cur_attr = mask2attr(tcp); - break; - } - for (i = 0; i < tcp->num_param; i++) { - switch (n = tcp->param[i]) { - case 0: /* back to normal */ - tcp->attr_mask = NORMAL_ATTR; - tcp->cur_color = tcp->std_color; - tcp->cur_attr = mask2attr(tcp); - break; - case 1: /* bold */ - tcp->attr_mask |= BOLD_ATTR; - tcp->cur_attr = mask2attr(tcp); - break; - case 4: /* underline */ - tcp->attr_mask |= UNDERLINE_ATTR; - tcp->cur_attr = mask2attr(tcp); - break; - case 5: /* blink */ - tcp->attr_mask |= BLINK_ATTR; - tcp->cur_attr = mask2attr(tcp); - break; - case 7: /* reverse */ - tcp->attr_mask |= REVERSE_ATTR; - tcp->cur_attr = mask2attr(tcp); - break; - case 22: /* remove bold (or dim) */ - tcp->attr_mask &= ~BOLD_ATTR; - tcp->cur_attr = mask2attr(tcp); - break; - case 24: /* remove underline */ - tcp->attr_mask &= ~UNDERLINE_ATTR; - tcp->cur_attr = mask2attr(tcp); - break; - case 25: /* remove blink */ - tcp->attr_mask &= ~BLINK_ATTR; - tcp->cur_attr = mask2attr(tcp); - break; - case 27: /* remove reverse */ - tcp->attr_mask &= ~REVERSE_ATTR; - tcp->cur_attr = mask2attr(tcp); - break; - case 30: case 31: /* set ansi fg color */ - case 32: case 33: case 34: - case 35: case 36: case 37: - tcp->attr_mask |= FG_CHANGED; - tcp->cur_color.fg = ansi_col[n - 30]; - tcp->cur_attr = mask2attr(tcp); - break; - case 39: /* restore fg color back to normal */ - tcp->attr_mask &= ~(FG_CHANGED|BOLD_ATTR); - tcp->cur_color.fg = tcp->std_color.fg; - tcp->cur_attr = mask2attr(tcp); - break; - case 40: case 41: /* set ansi bg color */ - case 42: case 43: case 44: - case 45: case 46: case 47: - tcp->attr_mask |= BG_CHANGED; - tcp->cur_color.bg = ansi_col[n - 40]; - tcp->cur_attr = mask2attr(tcp); - break; - case 49: /* restore bg color back to normal */ - tcp->attr_mask &= ~BG_CHANGED; - tcp->cur_color.bg = tcp->std_color.bg; - tcp->cur_attr = mask2attr(tcp); - break; - } - } - break; - - case 's': /* Save cursor position */ - tcp->saved_xpos = scp->xpos; - tcp->saved_ypos = scp->ypos; - break; - - case 'u': /* Restore saved cursor position */ - if (tcp->saved_xpos >= 0 && tcp->saved_ypos >= 0) - sc_move_cursor(scp, tcp->saved_xpos, - tcp->saved_ypos); - break; - - case 'x': - if (tcp->num_param == 0) - n = 0; - else - n = tcp->param[0]; - switch (n) { - case 0: /* reset colors and attributes back to normal */ - tcp->attr_mask = NORMAL_ATTR; - tcp->cur_color = tcp->std_color - = tcp->dflt_std_color; - tcp->rev_color = tcp->dflt_rev_color; - tcp->cur_attr = mask2attr(tcp); - break; - case 1: /* set ansi background */ - tcp->attr_mask &= ~BG_CHANGED; - tcp->cur_color.bg = tcp->std_color.bg - = ansi_col[tcp->param[1] & 0x0f]; - tcp->cur_attr = mask2attr(tcp); - break; - case 2: /* set ansi foreground */ - tcp->attr_mask &= ~FG_CHANGED; - tcp->cur_color.fg = tcp->std_color.fg - = ansi_col[tcp->param[1] & 0x0f]; - tcp->cur_attr = mask2attr(tcp); - break; - case 3: /* set adapter attribute directly */ - tcp->attr_mask &= ~(FG_CHANGED | BG_CHANGED); - tcp->cur_color.fg = tcp->std_color.fg - = tcp->param[1] & 0x0f; - tcp->cur_color.bg = tcp->std_color.bg - = (tcp->param[1] >> 4) & 0x0f; - tcp->cur_attr = mask2attr(tcp); - break; - case 5: /* set ansi reverse background */ - tcp->rev_color.bg = ansi_col[tcp->param[1] & 0x0f]; - tcp->cur_attr = mask2attr(tcp); - break; - case 6: /* set ansi reverse foreground */ - tcp->rev_color.fg = ansi_col[tcp->param[1] & 0x0f]; - tcp->cur_attr = mask2attr(tcp); - break; - case 7: /* set adapter reverse attribute directly */ - tcp->rev_color.fg = tcp->param[1] & 0x0f; - tcp->rev_color.bg = (tcp->param[1] >> 4) & 0x0f; - tcp->cur_attr = mask2attr(tcp); - break; - } - break; - - case 'z': /* switch to (virtual) console n */ - if (tcp->num_param == 1) - sc_switch_scr(sc, tcp->param[0]); - break; - } - } else if (tcp->esc == 3) { /* seen ESC [0-9]+ = */ - if (c >= '0' && c <= '9') { - if (tcp->num_param < MAX_ESC_PAR) { - if (tcp->last_param != tcp->num_param) { - tcp->last_param = tcp->num_param; - tcp->param[tcp->num_param] = 0; - } else { - tcp->param[tcp->num_param] *= 10; - } - tcp->param[tcp->num_param] += c - '0'; - return; - } - } - tcp->num_param = tcp->last_param + 1; - switch (c) { - - case ';': - if (tcp->num_param < MAX_ESC_PAR) - return; - break; - - case 'A': /* set display border color */ - if (tcp->num_param == 1) { - scp->border=tcp->param[0] & 0xff; - if (scp == sc->cur_scp) - sc_set_border(scp, scp->border); - } - break; - - case 'B': /* set bell pitch and duration */ - if (tcp->num_param == 2) { - scp->bell_pitch = tcp->param[0]; - scp->bell_duration = - (tcp->param[1] * hz + 99) / 100; - } - break; - - case 'C': /* set global/parmanent cursor type & shape */ - i = spltty(); - n = tcp->num_param; - v0 = tcp->param[0]; - v1 = tcp->param[1]; - v2 = tcp->param[2]; - switch (n) { - case 1: /* flags only */ - if (v0 < nitems(cattrs)) - v0 = cattrs[v0]; - else /* backward compatibility */ - v0 = cattrs[v0 & 0x3]; - sc_change_cursor_shape(scp, v0, -1, -1); - break; - case 2: - v2 = 0; - v0 &= 0x1f; /* backward compatibility */ - v1 &= 0x1f; - /* FALL THROUGH */ - case 3: /* base and height */ - if (v2 == 0) /* count from top */ - sc_change_cursor_shape(scp, -1, - scp->font_size - v1 - 1, - v1 - v0 + 1); - else if (v2 == 1) /* count from bottom */ - sc_change_cursor_shape(scp, -1, - v0, v1 - v0 + 1); - break; - } - splx(i); - break; - - case 'F': /* set adapter foreground */ - if (tcp->num_param == 1) { - tcp->attr_mask &= ~FG_CHANGED; - tcp->cur_color.fg = tcp->std_color.fg - = tcp->param[0] & 0x0f; - tcp->cur_attr = mask2attr(tcp); - } - break; - - case 'G': /* set adapter background */ - if (tcp->num_param == 1) { - tcp->attr_mask &= ~BG_CHANGED; - tcp->cur_color.bg = tcp->std_color.bg - = tcp->param[0] & 0x0f; - tcp->cur_attr = mask2attr(tcp); - } - break; - - case 'H': /* set adapter reverse foreground */ - if (tcp->num_param == 1) { - tcp->rev_color.fg = tcp->param[0] & 0x0f; - tcp->cur_attr = mask2attr(tcp); - } - break; - - case 'I': /* set adapter reverse background */ - if (tcp->num_param == 1) { - tcp->rev_color.bg = tcp->param[0] & 0x0f; - tcp->cur_attr = mask2attr(tcp); - } - break; - - case 'S': /* set local/temporary cursor type & shape */ - i = spltty(); - n = tcp->num_param; - v0 = tcp->param[0]; - switch (n) { - case 0: - v0 = 0; - /* FALL THROUGH */ - case 1: - if (v0 < nitems(tcattrs)) - sc_change_cursor_shape(scp, - tcattrs[v0], -1, -1); - break; - } - splx(i); - break; - } -#ifdef notyet - } else if (tcp->esc == 4) { /* seen ESC Q */ - /* to be filled */ -#endif - } else if (tcp->esc == 5) { /* seen ESC ( */ - switch (c) { - case 'B': /* iso-2022: desginate ASCII into G0 */ - break; - /* other items to be filled */ - default: - break; - } - } - tcp->esc = 0; -} - -static void -scterm_puts(scr_stat *scp, u_char *buf, int len, int kernel) -{ - term_stat *tcp; - u_char *ptr; -#ifdef KANJI - u_short kanji_code; -#endif - color_t backup; - - tcp = scp->ts; - ptr = buf; -outloop: - scp->sc->write_in_progress++; - backup = tcp->cur_color; - if (kernel) { - tcp->cur_color.fg = SC_KERNEL_CONS_ATTR & 0x0f; - tcp->cur_color.bg = (SC_KERNEL_CONS_ATTR >> 4) & 0x0f; - } - - if (tcp->esc) { - scterm_scan_esc(scp, tcp, *ptr++); - len--; - } else if (PRINTABLE(*ptr)) { /* Print only printables */ - vm_offset_t p; - u_char *map; - int attr; - int i; - int cnt; -#ifdef KANJI - u_char c; -#endif - - p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos); - map = scp->sc->scr_map; - attr = tcp->cur_attr; - -#ifdef KANJI - c = *ptr; - if (tcp->kanji_1st_char == 0) { - tcp->kanji_type = iskanji1(tcp->kanji_type, c); - if (!IS_KTYPE_ASCII_or_HANKAKU(tcp->kanji_type)) { - /* not Ascii & not HANKAKU */ - tcp->kanji_1st_char = c; - goto kanji_end; - } else if (tcp->kanji_type == KTYPE_ASCII) { - cnt = imin(len, scp->xsize - scp->xpos); - i = cnt; - do { - p = sc_vtb_putchar(&scp->vtb, p, map[c], attr); - c = *++ptr; - --i; - } while (i > 0 && PRINTABLE(c) && - iskanji1(tcp->kanji_type, c) == KTYPE_ASCII); - - len -= cnt - i; - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos += cnt - i; - mark_for_update(scp, scp->cursor_pos - 1); - scp->xpos += cnt - i; - KTYPE_MASK_CTRL(tcp->kanji_type); - goto ascii_end; - } - } else { - if ((tcp->kanji_type = - iskanji2(tcp->kanji_type, c)) & 0xee) { - /* print kanji on TEXT VRAM */ - kanji_code = kanji_convert(tcp->kanji_type, c, - tcp->kanji_1st_char); - mark_for_update(scp, scp->cursor_pos); - for (i = 0; i < 2; i++) { - /* *cursor_pos = (kanji_code | (i*0x80)); */ - p = sc_vtb_putchar(&scp->vtb, p, - kanji_code | ((i == 0) ? 0x00 : 0x80), attr); - ++scp->cursor_pos; - if (++scp->xpos >= scp->xsize) { - scp->xpos = 0; - scp->ypos++; - } - } - mark_for_update(scp, scp->cursor_pos - 1); - KTYPE_MASK_CTRL(tcp->kanji_type); - tcp->kanji_1st_char = 0; - goto kanji_end; - } else { - tcp->kanji_1st_char = 0; - } - } - if (IS_KTYPE_KANA(tcp->kanji_type)) - c |= 0x80; - KTYPE_MASK_CTRL(tcp->kanji_type); - sc_vtb_putchar(&scp->vtb, p, map[c], attr); - mark_for_update(scp, scp->cursor_pos); - mark_for_update(scp, scp->cursor_pos); - ++scp->cursor_pos; - ++scp->xpos; -kanji_end: - ++ptr; - --len; -ascii_end: -#else /* !KANJI */ - cnt = imin(len, scp->xsize - scp->xpos); - i = cnt; - do { - /* - * gcc-2.6.3 generates poor (un)sign extension code. - * Casting the pointers in the following to volatile should - * have no effect, but in fact speeds up this inner loop - * from 26 to 18 cycles (+ cache misses) on i486's. - */ -#define UCVP(ucp) ((u_char volatile *)(ucp)) - p = sc_vtb_putchar(&scp->vtb, p, UCVP(map)[*UCVP(ptr)], - attr); - ++ptr; - --i; - } while (i > 0 && PRINTABLE(*ptr)); - - len -= cnt - i; - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos += cnt - i; - mark_for_update(scp, scp->cursor_pos - 1); - scp->xpos += cnt - i; -#endif /* !KANJI */ - - if (scp->xpos >= scp->xsize) { - scp->xpos = 0; - scp->ypos++; - } - } else { - switch (*ptr) { - case 0x07: - sc_bell(scp, scp->bell_pitch, scp->bell_duration); - break; - - case 0x08: /* non-destructive backspace */ - if (scp->cursor_pos > 0) { - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos--; - mark_for_update(scp, scp->cursor_pos); - if (scp->xpos > 0) - scp->xpos--; - else { - scp->xpos += scp->xsize - 1; - scp->ypos--; - } - } - break; - - case 0x09: /* non-destructive tab */ - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos += (8 - scp->xpos % 8u); - scp->xpos += (8 - scp->xpos % 8u); - if (scp->xpos >= scp->xsize) { - scp->xpos = 0; - scp->ypos++; - scp->cursor_pos = scp->xsize * scp->ypos; - } - mark_for_update(scp, scp->cursor_pos); - break; - - case 0x0a: /* newline, same pos */ - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos += scp->xsize; - mark_for_update(scp, scp->cursor_pos); - scp->ypos++; - break; - - case 0x0c: /* form feed, clears screen */ - sc_clear_screen(scp); - break; - - case 0x0d: /* return, return to pos 0 */ - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos -= scp->xpos; - mark_for_update(scp, scp->cursor_pos); - scp->xpos = 0; - break; - - case 0x0e: /* ^N */ - tcp->kanji_type = KTYPE_JKANA; - tcp->esc = 0; - tcp->kanji_1st_char = 0; - break; - - case 0x0f: /* ^O */ - tcp->kanji_type = KTYPE_ASCII; - tcp->esc = 0; - tcp->kanji_1st_char = 0; - break; - - case 0x1b: /* start escape sequence */ - tcp->esc = 1; - tcp->num_param = 0; - break; - } - ptr++; - len--; - } - - sc_term_gen_scroll(scp, scp->sc->scr_map[0x20], tcp->cur_attr); - - if (kernel) - tcp->cur_color = backup; - scp->sc->write_in_progress--; - if (len) - goto outloop; -} - -static int -scterm_ioctl(scr_stat *scp, struct tty *tp, u_long cmd, caddr_t data, - struct thread *td) -{ - term_stat *tcp = scp->ts; - vid_info_t *vi; - - switch (cmd) { - case GIO_ATTR: /* get current attributes */ - /* FIXME: */ - *(int*)data = (tcp->cur_attr >> 8) & 0xff; - return 0; - case CONS_GETINFO: /* get current (virtual) console info */ - vi = (vid_info_t *)data; - if (vi->size != sizeof(struct vid_info)) - return EINVAL; - vi->mv_norm.fore = tcp->std_color.fg; - vi->mv_norm.back = tcp->std_color.bg; - vi->mv_rev.fore = tcp->rev_color.fg; - vi->mv_rev.back = tcp->rev_color.bg; - /* - * The other fields are filled by the upper routine. XXX - */ - return ENOIOCTL; - } - return ENOIOCTL; -} - -static int -scterm_reset(scr_stat *scp, int code) -{ - /* FIXME */ - return 0; -} - -static void -scterm_default_attr(scr_stat *scp, int color, int rev_color) -{ - term_stat *tcp = scp->ts; - - tcp->dflt_std_color.fg = color & 0x0f; - tcp->dflt_std_color.bg = (color >> 4) & 0x0f; - tcp->dflt_rev_color.fg = rev_color & 0x0f; - tcp->dflt_rev_color.bg = (rev_color >> 4) & 0x0f; - tcp->std_color = tcp->dflt_std_color; - tcp->rev_color = tcp->dflt_rev_color; - tcp->cur_color = tcp->std_color; - tcp->cur_attr = mask2attr(tcp); -} - -static void -scterm_clear(scr_stat *scp) -{ - term_stat *tcp = scp->ts; - - sc_move_cursor(scp, 0, 0); - sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], tcp->cur_attr); - mark_all(scp); -} - -static void -scterm_notify(scr_stat *scp, int event) -{ - switch (event) { - case SC_TE_NOTIFY_VTSWITCH_IN: - break; - case SC_TE_NOTIFY_VTSWITCH_OUT: - break; - } -} - -static int -scterm_input(scr_stat *scp, int c, struct tty *tp) -{ - return FALSE; -} - -static const char * -scterm_fkeystr(scr_stat *scp, int c) -{ - - return (NULL); -} - -/* - * Calculate hardware attributes word using logical attributes mask and - * hardware colors - */ - -/* FIXME */ -static int -mask2attr(term_stat *tcp) -{ - int attr, mask = tcp->attr_mask; - - if (mask & REVERSE_ATTR) { - attr = ((mask & FG_CHANGED) ? - tcp->cur_color.bg : tcp->rev_color.fg) | - (((mask & BG_CHANGED) ? - tcp->cur_color.fg : tcp->rev_color.bg) << 4); - } else - attr = tcp->cur_color.fg | (tcp->cur_color.bg << 4); - - /* XXX: underline mapping for Hercules adapter can be better */ - if (mask & (BOLD_ATTR | UNDERLINE_ATTR)) - attr ^= 0x08; - if (mask & BLINK_ATTR) - attr ^= 0x80; - - return (attr << 8); -} diff --git a/sys/pc98/cbus/sctermvar.h b/sys/pc98/cbus/sctermvar.h deleted file mode 100644 index b1c01af1f800..000000000000 --- a/sys/pc98/cbus/sctermvar.h +++ /dev/null @@ -1,432 +0,0 @@ -/*- - * Copyright (c) 1999 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 AUTHORS ``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 AUTHORS 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. - * - * $FreeBSD$ - */ - -#ifndef _DEV_SYSCONS_SCTERMVAR_H_ -#define _DEV_SYSCONS_SCTERMVAR_H_ - -/* - * building blocks for terminal emulator modules. - */ - -static __inline void sc_term_ins_line(scr_stat *scp, int y, int n, int ch, - int attr, int tail); -static __inline void sc_term_del_line(scr_stat *scp, int y, int n, int ch, - int attr, int tail); -static __inline void sc_term_ins_char(scr_stat *scp, int n, int ch, - int attr); -static __inline void sc_term_del_char(scr_stat *scp, int n, int ch, - int attr); -static __inline void sc_term_col(scr_stat *scp, int n); -static __inline void sc_term_row(scr_stat *scp, int n); -static __inline void sc_term_up(scr_stat *scp, int n, int head); -static __inline void sc_term_down(scr_stat *scp, int n, int tail); -static __inline void sc_term_left(scr_stat *scp, int n); -static __inline void sc_term_right(scr_stat *scp, int n); -static __inline void sc_term_up_scroll(scr_stat *scp, int n, int ch, - int attr, int head, int tail); -static __inline void sc_term_down_scroll(scr_stat *scp, int n, int ch, - int attr, int head, int tail); -static __inline void sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr); -static __inline void sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr); -static __inline void sc_term_tab(scr_stat *scp, int n); -static __inline void sc_term_backtab(scr_stat *scp, int n); -static __inline void sc_term_respond(scr_stat *scp, u_char *s); -static __inline void sc_term_gen_print(scr_stat *scp, u_char **buf, int *len, - int attr); -static __inline void sc_term_gen_scroll(scr_stat *scp, int ch, int attr); - -static __inline void -sc_term_ins_line(scr_stat *scp, int y, int n, int ch, int attr, int tail) -{ - if (tail <= 0) - tail = scp->ysize; - if (n < 1) - n = 1; - if (n > tail - y) - n = tail - y; - sc_vtb_ins(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr); - mark_for_update(scp, y*scp->xsize); - mark_for_update(scp, scp->xsize*tail - 1); -} - -static __inline void -sc_term_del_line(scr_stat *scp, int y, int n, int ch, int attr, int tail) -{ - if (tail <= 0) - tail = scp->ysize; - if (n < 1) - n = 1; - if (n > tail - y) - n = tail - y; - sc_vtb_delete(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr); - mark_for_update(scp, y*scp->xsize); - mark_for_update(scp, scp->xsize*tail - 1); -} - -static __inline void -sc_term_ins_char(scr_stat *scp, int n, int ch, int attr) -{ - int count; - - if (n < 1) - n = 1; - if (n > scp->xsize - scp->xpos) - n = scp->xsize - scp->xpos; - count = scp->xsize - (scp->xpos + n); - sc_vtb_move(&scp->vtb, scp->cursor_pos, scp->cursor_pos + n, count); - sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, ch, attr); - mark_for_update(scp, scp->cursor_pos); - mark_for_update(scp, scp->cursor_pos + n + count - 1); -} - -static __inline void -sc_term_del_char(scr_stat *scp, int n, int ch, int attr) -{ - int count; - - if (n < 1) - n = 1; - if (n > scp->xsize - scp->xpos) - n = scp->xsize - scp->xpos; - count = scp->xsize - (scp->xpos + n); - sc_vtb_move(&scp->vtb, scp->cursor_pos + n, scp->cursor_pos, count); - sc_vtb_erase(&scp->vtb, scp->cursor_pos + count, n, ch, attr); - mark_for_update(scp, scp->cursor_pos); - mark_for_update(scp, scp->cursor_pos + n + count - 1); -} - -static __inline void -sc_term_col(scr_stat *scp, int n) -{ - if (n < 1) - n = 1; - sc_move_cursor(scp, n - 1, scp->ypos); -} - -static __inline void -sc_term_row(scr_stat *scp, int n) -{ - if (n < 1) - n = 1; - sc_move_cursor(scp, scp->xpos, n - 1); -} - -static __inline void -sc_term_up(scr_stat *scp, int n, int head) -{ - if (n < 1) - n = 1; - n = imin(n, scp->ypos - head); - if (n <= 0) - return; - sc_move_cursor(scp, scp->xpos, scp->ypos - n); -} - -static __inline void -sc_term_down(scr_stat *scp, int n, int tail) -{ - if (tail <= 0) - tail = scp->ysize; - if (n < 1) - n = 1; - n = imin(n, tail - scp->ypos - 1); - if (n <= 0) - return; - sc_move_cursor(scp, scp->xpos, scp->ypos + n); -} - -static __inline void -sc_term_left(scr_stat *scp, int n) -{ - if (n < 1) - n = 1; - sc_move_cursor(scp, scp->xpos - n, scp->ypos); -} - -static __inline void -sc_term_right(scr_stat *scp, int n) -{ - if (n < 1) - n = 1; - sc_move_cursor(scp, scp->xpos + n, scp->ypos); -} - -static __inline void -sc_term_up_scroll(scr_stat *scp, int n, int ch, int attr, int head, int tail) -{ - if (tail <= 0) - tail = scp->ysize; - if (n < 1) - n = 1; - if (n <= scp->ypos - head) { - sc_move_cursor(scp, scp->xpos, scp->ypos - n); - } else { - sc_term_ins_line(scp, head, n - (scp->ypos - head), - ch, attr, tail); - sc_move_cursor(scp, scp->xpos, head); - } -} - -static __inline void -sc_term_down_scroll(scr_stat *scp, int n, int ch, int attr, int head, int tail) -{ - if (tail <= 0) - tail = scp->ysize; - if (n < 1) - n = 1; - if (n < tail - scp->ypos) { - sc_move_cursor(scp, scp->xpos, scp->ypos + n); - } else { - sc_term_del_line(scp, head, n - (tail - scp->ypos) + 1, - ch, attr, tail); - sc_move_cursor(scp, scp->xpos, tail - 1); - } -} - -static __inline void -sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr) -{ - switch (n) { - case 0: /* clear form cursor to end of display */ - sc_vtb_erase(&scp->vtb, scp->cursor_pos, - scp->xsize*scp->ysize - scp->cursor_pos, - ch, attr); - mark_for_update(scp, scp->cursor_pos); - mark_for_update(scp, scp->xsize*scp->ysize - 1); - sc_remove_cutmarking(scp); - break; - case 1: /* clear from beginning of display to cursor */ - sc_vtb_erase(&scp->vtb, 0, scp->cursor_pos + 1, ch, attr); - mark_for_update(scp, 0); - mark_for_update(scp, scp->cursor_pos); - sc_remove_cutmarking(scp); - break; - case 2: /* clear entire display */ - sc_vtb_erase(&scp->vtb, 0, scp->xsize*scp->ysize, ch, attr); - mark_for_update(scp, 0); - mark_for_update(scp, scp->xsize*scp->ysize - 1); - sc_remove_cutmarking(scp); - break; - } -} - -static __inline void -sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr) -{ - switch (n) { - case 0: /* clear form cursor to end of line */ - sc_vtb_erase(&scp->vtb, scp->cursor_pos, - scp->xsize - scp->xpos, ch, attr); - mark_for_update(scp, scp->cursor_pos); - mark_for_update(scp, scp->cursor_pos + - scp->xsize - 1 - scp->xpos); - break; - case 1: /* clear from beginning of line to cursor */ - sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos, - scp->xpos + 1, ch, attr); - mark_for_update(scp, scp->ypos*scp->xsize); - mark_for_update(scp, scp->cursor_pos); - break; - case 2: /* clear entire line */ - sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos, - scp->xsize, ch, attr); - mark_for_update(scp, scp->ypos*scp->xsize); - mark_for_update(scp, (scp->ypos + 1)*scp->xsize - 1); - break; - } -} - -static __inline void -sc_term_tab(scr_stat *scp, int n) -{ - int i; - - if (n < 1) - n = 1; - i = (scp->xpos & ~7) + 8*n; - if (i >= scp->xsize) { - if (scp->ypos >= scp->ysize - 1) { - scp->xpos = 0; - scp->ypos++; - scp->cursor_pos = scp->ypos*scp->xsize; - } else - sc_move_cursor(scp, 0, scp->ypos + 1); - } else - sc_move_cursor(scp, i, scp->ypos); -} - -static __inline void -sc_term_backtab(scr_stat *scp, int n) -{ - int i; - - if (n < 1) - n = 1; - if ((i = scp->xpos & ~7) == scp->xpos) - i -= 8*n; - else - i -= 8*(n - 1); - if (i < 0) - i = 0; - sc_move_cursor(scp, i, scp->ypos); -} - -static __inline void -sc_term_respond(scr_stat *scp, u_char *s) -{ - sc_paste(scp, s, strlen(s)); /* XXX: not correct, don't use rmap */ -} - -static __inline void -sc_term_gen_print(scr_stat *scp, u_char **buf, int *len, int attr) -{ - vm_offset_t p; - u_char *ptr; - u_char *map; - int cnt; - int l; - int i; - - ptr = *buf; - l = *len; - - if (PRINTABLE(*ptr)) { - p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos); - map = scp->sc->scr_map; - - cnt = imin(l, scp->xsize - scp->xpos); - i = cnt; - do { - p = sc_vtb_putchar(&scp->vtb, p, map[*ptr], attr); - ++ptr; - --i; - } while ((i > 0) && PRINTABLE(*ptr)); - - l -= cnt - i; - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos += cnt - i; - mark_for_update(scp, scp->cursor_pos - 1); - scp->xpos += cnt - i; - - if (scp->xpos >= scp->xsize) { - scp->xpos = 0; - scp->ypos++; - /* we may have to scroll the screen */ - } - } else { - switch(*ptr) { - case 0x07: - sc_bell(scp, scp->bell_pitch, scp->bell_duration); - break; - - case 0x08: /* non-destructive backspace */ - /* XXX */ - if (scp->cursor_pos > 0) { -#if 0 - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos--; - mark_for_update(scp, scp->cursor_pos); -#else - scp->cursor_pos--; -#endif - if (scp->xpos > 0) { - scp->xpos--; - } else { - scp->xpos += scp->xsize - 1; - scp->ypos--; - } - } - break; - - case 0x09: /* non-destructive tab */ - sc_term_tab(scp, 1); - /* we may have to scroll the screen */ -#if 0 - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos += (8 - scp->xpos % 8u); - mark_for_update(scp, scp->cursor_pos); - scp->xpos += (8 - scp->xpos % 8u); - if (scp->xpos >= scp->xsize) { - scp->xpos = 0; - scp->ypos++; - } -#endif - break; - - case 0x0a: /* newline, same pos */ -#if 0 - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos += scp->xsize; - mark_for_update(scp, scp->cursor_pos); -#else - scp->cursor_pos += scp->xsize; - /* we may have to scroll the screen */ -#endif - scp->ypos++; - break; - - case 0x0c: /* form feed, clears screen */ - sc_clear_screen(scp); - break; - - case 0x0d: /* return, return to pos 0 */ -#if 0 - mark_for_update(scp, scp->cursor_pos); - scp->cursor_pos -= scp->xpos; - mark_for_update(scp, scp->cursor_pos); -#else - scp->cursor_pos -= scp->xpos; -#endif - scp->xpos = 0; - break; - } - ptr++; l--; - } - - *buf = ptr; - *len = l; -} - -static __inline void -sc_term_gen_scroll(scr_stat *scp, int ch, int attr) -{ - /* do we have to scroll ?? */ - if (scp->cursor_pos >= scp->ysize*scp->xsize) { - sc_remove_cutmarking(scp); /* XXX */ -#ifndef SC_NO_HISTORY - if (scp->history != NULL) - sc_hist_save_one_line(scp, 0); /* XXX */ -#endif - sc_vtb_delete(&scp->vtb, 0, scp->xsize, ch, attr); - scp->cursor_pos -= scp->xsize; - scp->ypos--; - mark_all(scp); - } -} - -#endif /* _DEV_SYSCONS_SCTERMVAR_H_ */ diff --git a/sys/pc98/cbus/scvtb.c b/sys/pc98/cbus/scvtb.c deleted file mode 100644 index c25ef14938f9..000000000000 --- a/sys/pc98/cbus/scvtb.c +++ /dev/null @@ -1,399 +0,0 @@ -/*- - * Copyright (c) 1999 FreeBSD(98) Porting 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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. - * - * $FreeBSD$ - */ - -#include "opt_syscons.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/consio.h> -#include <sys/fbio.h> - -#include <machine/md_var.h> - -#include <dev/fb/fbreg.h> -#include <dev/syscons/syscons.h> - -#define ATTR_OFFSET_FB 0x2000 -#define attr_offset(vtb) ((vtb)->vtb_size*sizeof(u_int16_t)) - -#define vtb_pointer(vtb, at) \ - ((vtb)->vtb_buffer + sizeof(u_int16_t)*(at)) - -#define vtb_wrap(vtb, at, offset) \ - (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size) - -static u_int8_t ibmpc_to_pc98[256] = { - 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1, - 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9, - 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, - 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, - 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, - 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, - 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, - 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, - 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, - 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, - 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, - 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, - 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, - 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, - 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, - 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, - - 0x03, 0x23, 0x83, 0xa3, 0x43, 0x63, 0xc3, 0xe3, - 0x0b, 0x2b, 0x8b, 0xab, 0x4b, 0x6b, 0xcb, 0xeb, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, - 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, - 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, - 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, - 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, - 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, - 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, - 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, - 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, - 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, - 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, - 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, - 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, -}; -#define at2pc98(attr) ((attr) | ibmpc_to_pc98[(unsigned)(attr) >> 8]) - -void -sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait) -{ - vtb->vtb_flags = 0; - vtb->vtb_type = type; - vtb->vtb_cols = cols; - vtb->vtb_rows = rows; - vtb->vtb_size = cols*rows; - vtb->vtb_buffer = 0; - vtb->vtb_tail = 0; - - switch (type) { - case VTB_MEMORY: - case VTB_RINGBUFFER: - if ((buf == NULL) && (cols*rows != 0)) { - vtb->vtb_buffer = - (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2, - M_DEVBUF, - ((wait) ? M_WAITOK : M_NOWAIT) | M_ZERO); - if (vtb->vtb_buffer != 0) { - vtb->vtb_flags |= VTB_ALLOCED; - } - } else { - vtb->vtb_buffer = (vm_offset_t)buf; - } - vtb->vtb_flags |= VTB_VALID; - break; - case VTB_FRAMEBUFFER: - vtb->vtb_buffer = (vm_offset_t)buf; - vtb->vtb_flags |= VTB_VALID; - break; - default: - break; - } -} - -void -sc_vtb_destroy(sc_vtb_t *vtb) -{ - vm_offset_t p; - - vtb->vtb_cols = 0; - vtb->vtb_rows = 0; - vtb->vtb_size = 0; - vtb->vtb_tail = 0; - - p = vtb->vtb_buffer; - vtb->vtb_buffer = 0; - switch (vtb->vtb_type) { - case VTB_MEMORY: - case VTB_RINGBUFFER: - if ((vtb->vtb_flags & VTB_ALLOCED) && (p != 0)) - free((void *)p, M_DEVBUF); - break; - default: - break; - } - vtb->vtb_flags = 0; - vtb->vtb_type = VTB_INVALID; -} - -size_t -sc_vtb_size(int cols, int rows) -{ - return (size_t)(cols*rows*sizeof(u_int16_t)*2); -} - -int -sc_vtb_getc(sc_vtb_t *vtb, int at) -{ - vm_offset_t p = vtb_pointer(vtb, at); - - if (vtb->vtb_type == VTB_FRAMEBUFFER) - return (readw(p) & 0x00ff); - else - return (*(u_int16_t *)p & 0x00ff); -} - -int -sc_vtb_geta(sc_vtb_t *vtb, int at) -{ - vm_offset_t p = vtb_pointer(vtb, at); - - if (vtb->vtb_type == VTB_FRAMEBUFFER) - return (readw(p + ATTR_OFFSET_FB) & 0xff00); - else - return (*(u_int16_t *)(p + attr_offset(vtb)) & 0xff00); -} - -static inline void -vtb_putc(sc_vtb_t *vtb, vm_offset_t p, int c, int a) -{ - if (vtb->vtb_type == VTB_FRAMEBUFFER) { - writew(p, c); - writew(p + ATTR_OFFSET_FB, at2pc98(a)); - } else { - *(u_int16_t *)p = c; - *(u_int16_t *)(p + attr_offset(vtb)) = at2pc98(a); - } -} - -void -sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a) -{ - vtb_putc(vtb, vtb_pointer(vtb, at), c, a); -} - -vm_offset_t -sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a) -{ - vtb_putc(vtb, p, c, a); - return (p + sizeof(u_int16_t)); -} - -vm_offset_t -sc_vtb_pointer(sc_vtb_t *vtb, int at) -{ - return (vtb_pointer(vtb, at)); -} - -int -sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset) -{ - return ((pos + offset + vtb->vtb_size)%vtb->vtb_size); -} - -void -sc_vtb_clear(sc_vtb_t *vtb, int c, int attr) -{ - vm_offset_t p = vtb_pointer(vtb, 0); - - if (vtb->vtb_type == VTB_FRAMEBUFFER) { - fillw_io(c, p, vtb->vtb_size); - fillw_io(at2pc98(attr), p + ATTR_OFFSET_FB, vtb->vtb_size); - } else { - fillw(c, (void *)p, vtb->vtb_size); - fillw(at2pc98(attr), (void *)(p + attr_offset(vtb)), - vtb->vtb_size); - } -} - -void -sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count) -{ - vm_offset_t p1, p2; - - p1 = vtb_pointer(vtb1, from); - p2 = vtb_pointer(vtb2, to); - if (vtb2->vtb_type == VTB_FRAMEBUFFER) { - bcopy_toio(p1, p2, count*sizeof(u_int16_t)); - bcopy_toio(p1 + attr_offset(vtb1), - p2 + ATTR_OFFSET_FB, - count*sizeof(u_int16_t)); - } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) { - bcopy_fromio(p1, p2, count*sizeof(u_int16_t)); - bcopy_fromio(p1 + ATTR_OFFSET_FB, - p2 + attr_offset(vtb2), - count*sizeof(u_int16_t)); - } else { - bcopy((void *)p1, (void *)p2, count*sizeof(u_int16_t)); - bcopy((void *)(p1 + attr_offset(vtb1)), - (void *)(p2 + attr_offset(vtb2)), - count*sizeof(u_int16_t)); - } -} - -void -sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count) -{ - int len; - vm_offset_t p1, p2; - - if (vtb2->vtb_type != VTB_RINGBUFFER) - return; - - while (count > 0) { - p1 = vtb_pointer(vtb1, from); - p2 = vtb_pointer(vtb2, vtb2->vtb_tail); - len = imin(count, vtb2->vtb_size - vtb2->vtb_tail); - if (vtb1->vtb_type == VTB_FRAMEBUFFER) { - bcopy_fromio(p1, p2, len*sizeof(u_int16_t)); - bcopy_fromio(p1 + ATTR_OFFSET_FB, - p2 + attr_offset(vtb2), - len*sizeof(u_int16_t)); - } else { - bcopy((void *)p1, (void *)p2, len*sizeof(u_int16_t)); - bcopy((void *)(p1 + attr_offset(vtb1)), - (void *)(p2 + attr_offset(vtb2)), - len*sizeof(u_int16_t)); - } - from += len; - count -= len; - vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len); - } -} - -void -sc_vtb_seek(sc_vtb_t *vtb, int pos) -{ - vtb->vtb_tail = pos%vtb->vtb_size; -} - -void -sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr) -{ - vm_offset_t p; - - if (at + count > vtb->vtb_size) - count = vtb->vtb_size - at; - p = vtb_pointer(vtb, at); - if (vtb->vtb_type == VTB_FRAMEBUFFER) { - fillw_io(c, p, count); - fillw_io(at2pc98(attr), p + ATTR_OFFSET_FB, count); - } else { - fillw(c, (void *)p, count); - fillw(at2pc98(attr), (void *)(p + attr_offset(vtb)), count); - } -} - -void -sc_vtb_move(sc_vtb_t *vtb, int from, int to, int count) -{ - vm_offset_t p1, p2; - - if (from + count > vtb->vtb_size) - count = vtb->vtb_size - from; - if (to + count > vtb->vtb_size) - count = vtb->vtb_size - to; - if (count <= 0) - return; - - p1 = vtb_pointer(vtb, from); - p2 = vtb_pointer(vtb, to); - if (vtb->vtb_type == VTB_FRAMEBUFFER) { - bcopy_io(p1, p2, count*sizeof(u_int16_t)); - bcopy_io(p1 + ATTR_OFFSET_FB, - p2 + ATTR_OFFSET_FB, count*sizeof(u_int16_t)); - } else { - bcopy((void *)p1, (void *)p2, count*sizeof(u_int16_t)); - bcopy((void *)(p1 + attr_offset(vtb)), - (void *)(p2 + attr_offset(vtb)), count*sizeof(u_int16_t)); - } -} - -void -sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr) -{ - int len; - vm_offset_t p1, p2; - - if (at + count > vtb->vtb_size) - count = vtb->vtb_size - at; - len = vtb->vtb_size - at - count; - if (len > 0) { - p1 = vtb_pointer(vtb, at + count); - p2 = vtb_pointer(vtb, at); - if (vtb->vtb_type == VTB_FRAMEBUFFER) { - bcopy_io(p1, p2, len*sizeof(u_int16_t)); - bcopy_io(p1 + ATTR_OFFSET_FB, - p2 + ATTR_OFFSET_FB, - len*sizeof(u_int16_t)); - } else { - bcopy((void *)p1, (void *)p2, len*sizeof(u_int16_t)); - bcopy((void *)(p1 + attr_offset(vtb)), - (void *)(p2 + attr_offset(vtb)), - len*sizeof(u_int16_t)); - } - } - p1 = vtb_pointer(vtb, at + len); - if (vtb->vtb_type == VTB_FRAMEBUFFER) { - fillw_io(c, p1, vtb->vtb_size - at - len); - fillw_io(at2pc98(attr), p1 + ATTR_OFFSET_FB, - vtb->vtb_size - at - len); - } else { - fillw(c, (void *)p1, vtb->vtb_size - at - len); - fillw(at2pc98(attr), (void *)(p1 + attr_offset(vtb)), - vtb->vtb_size - at - len); - } -} - -void -sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr) -{ - vm_offset_t p1, p2; - - p1 = vtb_pointer(vtb, at); - if (at + count > vtb->vtb_size) { - count = vtb->vtb_size - at; - } else { - p2 = vtb_pointer(vtb, at + count); - if (vtb->vtb_type == VTB_FRAMEBUFFER) { - bcopy_io(p1, p2, - (vtb->vtb_size - at - count)*sizeof(u_int16_t)); - bcopy_io(p1 + ATTR_OFFSET_FB, - p2 + ATTR_OFFSET_FB, - (vtb->vtb_size - at - count)*sizeof(u_int16_t)); - } else { - bcopy((void *)p1, (void *)p2, - (vtb->vtb_size - at - count)*sizeof(u_int16_t)); - bcopy((void *)(p1 + attr_offset(vtb)), - (void *)(p2 + attr_offset(vtb)), - (vtb->vtb_size - at - count)*sizeof(u_int16_t)); - } - } - if (vtb->vtb_type == VTB_FRAMEBUFFER) { - fillw_io(c, p1, count); - fillw_io(at2pc98(attr), p1 + ATTR_OFFSET_FB, count); - } else { - fillw(c, (void *)p1, count); - fillw(at2pc98(attr), (void *)(p1 + attr_offset(vtb)), count); - } -} diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c deleted file mode 100644 index 3e793680ea2b..000000000000 --- a/sys/pc98/cbus/sio.c +++ /dev/null @@ -1,4387 +0,0 @@ -/*- - * 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. - * 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. - * - * $FreeBSD$ - * from: @(#)com.c 7.5 (Berkeley) 5/16/91 - * from: i386/isa sio.c,v 1.234 - */ - -#include "opt_compat.h" -#include "opt_gdb.h" -#include "opt_kdb.h" -#include "opt_sio.h" - -/* - * Serial driver, based on 386BSD-0.1 com driver. - * Mostly rewritten to use pseudo-DMA. - * Works for National Semiconductor NS8250-NS16550AF UARTs. - * COM driver, based on HP dca driver. - * - * Changes for PC Card integration: - * - Added PC Card driver table and handlers - */ -/*=============================================================== - * 386BSD(98),FreeBSD-1.1x(98) com driver. - * ----- - * modified for PC9801 by M.Ishii - * Kyoto University Microcomputer Club (KMC) - * Chou "TEFUTEFU" Hirotomi - * Kyoto Univ. the faculty of medicine - *=============================================================== - * FreeBSD-2.0.1(98) sio driver. - * ----- - * modified for pc98 Internal i8251 and MICRO CORE MC16550II - * T.Koike(hfc01340@niftyserve.or.jp) - * implement kernel device configuration - * aizu@orient.center.nitech.ac.jp - * - * Notes. - * ----- - * PC98 localization based on 386BSD(98) com driver. Using its PC98 local - * functions. - * This driver is under debugging,has bugs. - */ -/* - * modified for AIWA B98-01 - * by T.Hatanou <hatanou@yasuda.comm.waseda.ac.jp> last update: 15 Sep.1995 - */ -/* - * Modified by Y.Takahashi of Kogakuin University. - */ -/* - * modified for 8251(FIFO) by Seigo TANIMURA <tanimura@FreeBSD.org> - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/conf.h> -#include <sys/fcntl.h> -#include <sys/interrupt.h> -#include <sys/kdb.h> -#include <sys/kernel.h> -#include <sys/limits.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/module.h> -#include <sys/mutex.h> -#include <sys/proc.h> -#include <sys/reboot.h> -#include <sys/serial.h> -#include <sys/sysctl.h> -#include <sys/syslog.h> -#include <sys/tty.h> -#include <machine/bus.h> -#include <sys/rman.h> -#include <sys/timepps.h> -#include <sys/uio.h> -#include <sys/cons.h> - -#include <isa/isavar.h> - -#include <machine/resource.h> - -#include <dev/sio/sioreg.h> -#include <dev/sio/siovar.h> - -#ifdef PC98 -#include <pc98/cbus/cbus.h> -#include <pc98/pc98/pc98_machdep.h> -#endif - -#ifdef COM_ESP -#include <dev/ic/esp.h> -#endif -#include <dev/ic/ns16550.h> -#ifdef PC98 -#include <dev/ic/i8251.h> -#include <dev/ic/i8255.h> -#include <dev/ic/rsa.h> -#endif - -#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */ - -/* - * Meaning of flags: - * - * 0x00000001 shared IRQs - * 0x00000002 disable FIFO - * 0x00000008 recover sooner from lost output interrupts - * 0x00000010 device is potential system console - * 0x00000020 device is forced to become system console - * 0x00000040 device is reserved for low-level IO - * 0x00000080 use this port for remote kernel debugging - * 0x0000??00 minor number of master port - * 0x00010000 PPS timestamping on CTS instead of DCD - * 0x00080000 IIR_TXRDY bug - * 0x00400000 If no comconsole found then mark as a comconsole - * 0x1?000000 interface type - */ - -#ifdef COM_MULTIPORT -/* checks in flags for multiport and which is multiport "master chip" - * for a given card - */ -#define COM_ISMULTIPORT(flags) ((flags) & 0x01) -#define COM_MPMASTER(flags) (((flags) >> 8) & 0x0ff) -#ifndef PC98 -#define COM_NOTAST4(flags) ((flags) & 0x04) -#endif -#else -#define COM_ISMULTIPORT(flags) (0) -#endif /* COM_MULTIPORT */ - -#define COM_C_IIR_TXRDYBUG 0x80000 -#define COM_CONSOLE(flags) ((flags) & 0x10) -#define COM_DEBUGGER(flags) ((flags) & 0x80) -#ifndef PC98 -#define COM_FIFOSIZE(flags) (((flags) & 0xff000000) >> 24) -#endif -#define COM_FORCECONSOLE(flags) ((flags) & 0x20) -#define COM_IIR_TXRDYBUG(flags) ((flags) & COM_C_IIR_TXRDYBUG) -#define COM_LLCONSOLE(flags) ((flags) & 0x40) -#define COM_LOSESOUTINTS(flags) ((flags) & 0x08) -#define COM_NOFIFO(flags) ((flags) & 0x02) -#ifndef PC98 -#define COM_NOSCR(flags) ((flags) & 0x100000) -#endif -#define COM_PPSCTS(flags) ((flags) & 0x10000) -#ifndef PC98 -#define COM_ST16650A(flags) ((flags) & 0x20000) -#define COM_TI16754(flags) ((flags) & 0x200000) -#endif - -#define sio_getreg(com, off) \ - (bus_space_read_1((com)->bst, (com)->bsh, (off))) -#define sio_setreg(com, off, value) \ - (bus_space_write_1((com)->bst, (com)->bsh, (off), (value))) - -/* - * com state bits. - * (CS_BUSY | CS_TTGO) and (CS_BUSY | CS_TTGO | CS_ODEVREADY) must be higher - * than the other bits so that they can be tested as a group without masking - * off the low bits. - * - * The following com and tty flags correspond closely: - * CS_BUSY = TS_BUSY (maintained by comstart(), siopoll() and - * comstop()) - * CS_TTGO = ~TS_TTSTOP (maintained by comparam() and comstart()) - * CS_CTS_OFLOW = CCTS_OFLOW (maintained by comparam()) - * CS_RTS_IFLOW = CRTS_IFLOW (maintained by comparam()) - * TS_FLUSH is not used. - * XXX I think TIOCSETA doesn't clear TS_TTSTOP when it clears IXON. - * XXX CS_*FLOW should be CF_*FLOW in com->flags (control flags not state). - */ -#define CS_BUSY 0x80 /* output in progress */ -#define CS_TTGO 0x40 /* output not stopped by XOFF */ -#define CS_ODEVREADY 0x20 /* external device h/w ready (CTS) */ -#define CS_CHECKMSR 1 /* check of MSR scheduled */ -#define CS_CTS_OFLOW 2 /* use CTS output flow control */ -#define CS_ODONE 4 /* output completed */ -#define CS_RTS_IFLOW 8 /* use RTS input flow control */ -#define CSE_BUSYCHECK 1 /* siobusycheck() scheduled */ - -static char const * const error_desc[] = { -#define CE_OVERRUN 0 - "silo overflow", -#define CE_INTERRUPT_BUF_OVERFLOW 1 - "interrupt-level buffer overflow", -#define CE_TTY_BUF_OVERFLOW 2 - "tty-level buffer overflow", -}; - -#define CE_NTYPES 3 -#define CE_RECORD(com, errnum) (++(com)->delta_error_counts[errnum]) - -/* types. XXX - should be elsewhere */ -typedef u_int Port_t; /* hardware port */ -typedef u_char bool_t; /* boolean */ - -/* queue of linear buffers */ -struct lbq { - u_char *l_head; /* next char to process */ - u_char *l_tail; /* one past the last char to process */ - struct lbq *l_next; /* next in queue */ - bool_t l_queued; /* nonzero if queued */ -}; - -/* com device structure */ -struct com_s { - u_char state; /* miscellaneous flag bits */ - u_char cfcr_image; /* copy of value written to CFCR */ -#ifdef COM_ESP - bool_t esp; /* is this unit a hayes esp board? */ -#endif - u_char extra_state; /* more flag bits, separate for order trick */ - u_char fifo_image; /* copy of value written to FIFO */ - bool_t hasfifo; /* nonzero for 16550 UARTs */ - bool_t loses_outints; /* nonzero if device loses output interrupts */ - u_char mcr_image; /* copy of value written to MCR */ -#ifdef COM_MULTIPORT - bool_t multiport; /* is this unit part of a multiport device? */ -#endif /* COM_MULTIPORT */ - bool_t no_irq; /* nonzero if irq is not attached */ - bool_t gone; /* hardware disappeared */ - bool_t poll; /* nonzero if polling is required */ - bool_t poll_output; /* nonzero if polling for output is required */ - bool_t st16650a; /* nonzero if Startech 16650A compatible */ - int unit; /* unit number */ - u_int flags; /* copy of device flags */ - u_int tx_fifo_size; - - /* - * The high level of the driver never reads status registers directly - * because there would be too many side effects to handle conveniently. - * Instead, it reads copies of the registers stored here by the - * interrupt handler. - */ - u_char last_modem_status; /* last MSR read by intr handler */ - u_char prev_modem_status; /* last MSR handled by high level */ - - u_char *ibuf; /* start of input buffer */ - u_char *ibufend; /* end of input buffer */ - u_char *ibufold; /* old input buffer, to be freed */ - u_char *ihighwater; /* threshold in input buffer */ - u_char *iptr; /* next free spot in input buffer */ - int ibufsize; /* size of ibuf (not include error bytes) */ - int ierroff; /* offset of error bytes in ibuf */ - - struct lbq obufq; /* head of queue of output buffers */ - struct lbq obufs[2]; /* output buffers */ - - bus_space_tag_t bst; - bus_space_handle_t bsh; - -#ifdef PC98 - Port_t cmd_port; - Port_t sts_port; - Port_t in_modem_port; - Port_t intr_ctrl_port; - Port_t rsabase; /* Iobase address of an I/O-DATA RSA board. */ - int intr_enable; - int pc98_prev_modem_status; - int pc98_modem_delta; - int modem_car_chg_timer; - int pc98_prev_siocmd; - int pc98_prev_siomod; - int modem_checking; - int pc98_if_type; - - bool_t pc98_8251fifo; - bool_t pc98_8251fifo_enable; -#endif /* PC98 */ - Port_t data_port; /* i/o ports */ -#ifdef COM_ESP - Port_t esp_port; -#endif - Port_t int_ctl_port; - Port_t int_id_port; - Port_t modem_ctl_port; - Port_t line_status_port; - Port_t modem_status_port; - - struct tty *tp; /* cross reference */ - - struct pps_state pps; - int pps_bit; -#ifdef KDB - int alt_brk_state; -#endif - - u_long bytes_in; /* statistics */ - u_long bytes_out; - u_int delta_error_counts[CE_NTYPES]; - u_long error_counts[CE_NTYPES]; - - u_long rclk; - - struct resource *irqres; - struct resource *ioportres; - int ioportrid; - void *cookie; - - /* - * Data area for output buffers. Someday we should build the output - * buffer queue without copying data. - */ -#ifdef PC98 - int obufsize; - u_char *obuf1; - u_char *obuf2; -#else - u_char obuf1[256]; - u_char obuf2[256]; -#endif -}; - -#ifdef COM_ESP -static int espattach(struct com_s *com, Port_t esp_port); -#endif - -static void combreak(struct tty *tp, int sig); -static timeout_t siobusycheck; -static u_int siodivisor(u_long rclk, speed_t speed); -static void comclose(struct tty *tp); -static int comopen(struct tty *tp, struct cdev *dev); -static void sioinput(struct com_s *com); -static void siointr1(struct com_s *com); -static int siointr(void *arg); -static int commodem(struct tty *tp, int sigon, int sigoff); -static int comparam(struct tty *tp, struct termios *t); -static void siopoll(void *); -static void siosettimeout(void); -static int siosetwater(struct com_s *com, speed_t speed); -static void comstart(struct tty *tp); -static void comstop(struct tty *tp, int rw); -static timeout_t comwakeup; - -char sio_driver_name[] = "sio"; -static struct mtx sio_lock; -static int sio_inited; - -/* table and macro for fast conversion from a unit number to its com struct */ -devclass_t sio_devclass; -#define com_addr(unit) ((struct com_s *) \ - devclass_get_softc(sio_devclass, unit)) /* XXX */ - -int comconsole = -1; -static volatile speed_t comdefaultrate = CONSPEED; -static u_long comdefaultrclk = DEFAULT_RCLK; -SYSCTL_ULONG(_machdep, OID_AUTO, conrclk, CTLFLAG_RW, &comdefaultrclk, 0, ""); -static speed_t gdbdefaultrate = GDBSPEED; -SYSCTL_UINT(_machdep, OID_AUTO, gdbspeed, CTLFLAG_RW, - &gdbdefaultrate, GDBSPEED, ""); -static u_int com_events; /* input chars + weighted output completions */ -static Port_t siocniobase; -static int siocnunit = -1; -static void *sio_slow_ih; -static void *sio_fast_ih; -static int sio_timeout; -static int sio_timeouts_until_log; -static struct callout_handle sio_timeout_handle - = CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle); -static int sio_numunits; - -#ifdef PC98 -struct siodev { - short if_type; - short irq; - Port_t cmd, sts, ctrl, mod; -}; -static int sysclock; - -#define COM_INT_DISABLE {int previpri; previpri=spltty(); -#define COM_INT_ENABLE splx(previpri);} -#define IEN_TxFLAG IEN_Tx - -#define COM_CARRIER_DETECT_EMULATE 0 -#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 - -static void commint(struct cdev *dev); -static void com_tiocm_bis(struct com_s *com, int msr); -static void com_tiocm_bic(struct com_s *com, int msr); -static int com_tiocm_get(struct com_s *com); -static int com_tiocm_get_delta(struct com_s *com); -static void pc98_msrint_start(struct cdev *dev); -static void com_cflag_and_speed_set(struct com_s *com, int cflag, int speed); -static int pc98_ttspeedtab(struct com_s *com, int speed, u_int *divisor); -static int pc98_get_modem_status(struct com_s *com); -static timeout_t pc98_check_msr; -static void pc98_set_baud_rate(struct com_s *com, u_int count); -static void pc98_i8251_reset(struct com_s *com, int mode, int command); -static void pc98_disable_i8251_interrupt(struct com_s *com, int mod); -static void pc98_enable_i8251_interrupt(struct com_s *com, int mod); -static int pc98_check_i8251_interrupt(struct com_s *com); -static int pc98_i8251_get_cmd(struct com_s *com); -static int pc98_i8251_get_mod(struct com_s *com); -static void pc98_i8251_set_cmd(struct com_s *com, int x); -static void pc98_i8251_or_cmd(struct com_s *com, int x); -static void pc98_i8251_clear_cmd(struct com_s *com, int x); -static void pc98_i8251_clear_or_cmd(struct com_s *com, int clr, int x); -static int pc98_check_if_type(device_t dev, struct siodev *iod); -static int pc98_check_8251vfast(void); -static int pc98_check_8251fifo(void); -static void pc98_check_sysclock(void); -static void pc98_set_ioport(struct com_s *com); - -#define com_int_Tx_disable(com) \ - pc98_disable_i8251_interrupt(com,IEN_Tx|IEN_TxEMP) -#define com_int_Tx_enable(com) \ - pc98_enable_i8251_interrupt(com,IEN_TxFLAG) -#define com_int_Rx_disable(com) \ - pc98_disable_i8251_interrupt(com,IEN_Rx) -#define com_int_Rx_enable(com) \ - pc98_enable_i8251_interrupt(com,IEN_Rx) -#define com_int_TxRx_disable(com) \ - pc98_disable_i8251_interrupt(com,IEN_Tx|IEN_TxEMP|IEN_Rx) -#define com_int_TxRx_enable(com) \ - pc98_enable_i8251_interrupt(com,IEN_TxFLAG|IEN_Rx) -#define com_send_break_on(com) \ - (IS_8251((com)->pc98_if_type) ? \ - pc98_i8251_or_cmd((com), CMD8251_SBRK) : \ - sio_setreg((com), com_cfcr, (com)->cfcr_image |= CFCR_SBREAK)) -#define com_send_break_off(com) \ - (IS_8251((com)->pc98_if_type) ? \ - pc98_i8251_clear_cmd((com), CMD8251_SBRK) : \ - sio_setreg((com), com_cfcr, (com)->cfcr_image &= ~CFCR_SBREAK)) - -static struct speedtab pc98speedtab[] = { /* internal RS232C interface */ - { 0, 0, }, - { 50, 50, }, - { 75, 75, }, - { 150, 150, }, - { 200, 200, }, - { 300, 300, }, - { 600, 600, }, - { 1200, 1200, }, - { 2400, 2400, }, - { 4800, 4800, }, - { 9600, 9600, }, - { 19200, 19200, }, - { 38400, 38400, }, - { 51200, 51200, }, - { 76800, 76800, }, - { 20800, 20800, }, - { 31200, 31200, }, - { 41600, 41600, }, - { 62400, 62400, }, - { -1, -1 } -}; -static struct speedtab pc98fast_speedtab[] = { - { 9600, 0x80 | (DEFAULT_RCLK / (16 * (9600))), }, - { 19200, 0x80 | (DEFAULT_RCLK / (16 * (19200))), }, - { 38400, 0x80 | (DEFAULT_RCLK / (16 * (38400))), }, - { 57600, 0x80 | (DEFAULT_RCLK / (16 * (57600))), }, - { 115200, 0x80 | (DEFAULT_RCLK / (16 * (115200))), }, - { -1, -1 } -}; -static struct speedtab comspeedtab_pio9032b[] = { - { 300, 6, }, - { 600, 5, }, - { 1200, 4, }, - { 2400, 3, }, - { 4800, 2, }, - { 9600, 1, }, - { 19200, 0, }, - { 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_ind[] = { - { 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, }, - { -1, -1 } -}; - -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_ind, 1 }, - /* COM_IF_IND_SS_2 */ - { " (IND-SS)", {0xb9, 0xbb, 0xbb, 0xb2, 0xb2, 0xbb, -1}, - 3, comspeedtab_ind, 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]) - -#define I8251F_data 0x130 -#define I8251F_lsr 0x132 -#define I8251F_msr 0x134 -#define I8251F_iir 0x136 -#define I8251F_fcr 0x138 -#define I8251F_div 0x13a - - -static bus_addr_t port_table_0[] = - {0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007}; -static bus_addr_t port_table_1[] = - {0x000, 0x002, 0x004, 0x006, 0x008, 0x00a, 0x00c, 0x00e}; -static bus_addr_t port_table_8[] = - {0x000, 0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700}; -static bus_addr_t port_table_rsa[] = { - 0x008, 0x009, 0x00a, 0x00b, 0x00c, 0x00d, 0x00e, 0x00f, - 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007 -}; - -struct { - char *name; - short irr_read; - short irr_write; - bus_addr_t *iat; - bus_size_t iatsz; - u_long rclk; -} if_16550a_type[] = { - /* COM_IF_RSA98 */ - {" (RSA-98)", -1, -1, port_table_0, IO_COMSIZE, DEFAULT_RCLK}, - /* COM_IF_NS16550 */ - {"", -1, -1, port_table_0, IO_COMSIZE, DEFAULT_RCLK}, - /* COM_IF_SECOND_CCU */ - {"", -1, -1, port_table_0, IO_COMSIZE, DEFAULT_RCLK}, - /* COM_IF_MC16550II */ - {" (MC16550II)", -1, 0x1000, port_table_8, IO_COMSIZE, - DEFAULT_RCLK * 4}, - /* COM_IF_MCRS98 */ - {" (MC-RS98)", -1, 0x1000, port_table_8, IO_COMSIZE, DEFAULT_RCLK * 4}, - /* COM_IF_RSB3000 */ - {" (RSB-3000)", 0xbf, -1, port_table_1, IO_COMSIZE, DEFAULT_RCLK * 10}, - /* COM_IF_RSB384 */ - {" (RSB-384)", 0xbf, -1, port_table_1, IO_COMSIZE, DEFAULT_RCLK * 10}, - /* COM_IF_MODEM_CARD */ - {"", -1, -1, port_table_0, IO_COMSIZE, DEFAULT_RCLK}, - /* COM_IF_RSA98III */ - {" (RSA-98III)", -1, -1, port_table_rsa, 16, DEFAULT_RCLK * 8}, - /* COM_IF_ESP98 */ - {" (ESP98)", -1, -1, port_table_1, IO_COMSIZE, DEFAULT_RCLK * 4}, -}; -#endif /* PC98 */ - -#ifdef GDB -static Port_t siogdbiobase = 0; -#endif - -#ifdef COM_ESP -#ifdef PC98 - -/* XXX configure this properly. */ -/* XXX quite broken for new-bus. */ -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 - -/* - * handle sysctl read/write requests for console speed - * - * In addition to setting comdefaultrate for I/O through /dev/console, - * also set the initial and lock values for the /dev/ttyXX device - * if there is one associated with the console. Finally, if the /dev/tty - * device has already been open, change the speed on the open running port - * itself. - */ - -static int -sysctl_machdep_comdefaultrate(SYSCTL_HANDLER_ARGS) -{ - int error, s; - speed_t newspeed; - struct com_s *com; - struct tty *tp; - - newspeed = comdefaultrate; - - error = sysctl_handle_opaque(oidp, &newspeed, sizeof newspeed, req); - if (error || !req->newptr) - return (error); - - comdefaultrate = newspeed; - - if (comconsole < 0) /* serial console not selected? */ - return (0); - - com = com_addr(comconsole); - if (com == NULL) - return (ENXIO); - - tp = com->tp; - if (tp == NULL) - return (ENXIO); - - /* - * set the initial and lock rates for /dev/ttydXX and /dev/cuaXX - * (note, the lock rates really are boolean -- if non-zero, disallow - * speed changes) - */ - tp->t_init_in.c_ispeed = tp->t_init_in.c_ospeed = - tp->t_lock_in.c_ispeed = tp->t_lock_in.c_ospeed = - tp->t_init_out.c_ispeed = tp->t_init_out.c_ospeed = - tp->t_lock_out.c_ispeed = tp->t_lock_out.c_ospeed = comdefaultrate; - - if (tp->t_state & TS_ISOPEN) { - tp->t_termios.c_ispeed = - tp->t_termios.c_ospeed = comdefaultrate; - s = spltty(); - error = comparam(tp, &tp->t_termios); - splx(s); - } - return error; -} - -SYSCTL_PROC(_machdep, OID_AUTO, conspeed, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NOFETCH, - 0, 0, sysctl_machdep_comdefaultrate, "I", ""); -TUNABLE_INT("machdep.conspeed", __DEVOLATILE(int *, &comdefaultrate)); - -/* - * Unload the driver and clear the table. - * XXX this is mostly wrong. - * XXX TODO: - * This is usually called when the card is ejected, but - * can be caused by a kldunload 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. - */ -int -siodetach(device_t dev) -{ - struct com_s *com; - - com = (struct com_s *) device_get_softc(dev); - if (com == NULL) { - device_printf(dev, "NULL com in siounload\n"); - return (0); - } - com->gone = TRUE; - if (com->tp) - ttyfree(com->tp); - if (com->irqres) { - bus_teardown_intr(dev, com->irqres, com->cookie); - bus_release_resource(dev, SYS_RES_IRQ, 0, com->irqres); - } - if (com->ioportres) - bus_release_resource(dev, SYS_RES_IOPORT, com->ioportrid, - com->ioportres); - if (com->ibuf != NULL) - free(com->ibuf, M_DEVBUF); -#ifdef PC98 - if (com->obuf1 != NULL) - free(com->obuf1, M_DEVBUF); -#endif - - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - return (0); -} - -int -sioprobe(dev, xrid, rclk, noprobe) - device_t dev; - int xrid; - u_long rclk; - int noprobe; -{ -#if 0 - static bool_t already_init; - device_t xdev; -#endif - struct com_s *com; - u_int divisor; - bool_t failures[10]; - int fn; - device_t idev; - Port_t iobase; - intrmask_t irqmap[4]; - intrmask_t irqs; - u_char mcr_image; - int result; - u_long xirq; - u_int flags = device_get_flags(dev); - int rid; - struct resource *port; -#ifdef PC98 - int tmp; - struct siodev iod; -#endif - -#ifdef PC98 - iod.if_type = GET_IFTYPE(flags); - if ((iod.if_type < 0 || iod.if_type > COM_IF_END1) && - (iod.if_type < 0x10 || iod.if_type > COM_IF_END2)) - return ENXIO; -#endif - - rid = xrid; -#ifdef PC98 - if (IS_8251(iod.if_type)) { - port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, - RF_ACTIVE); - } else if (iod.if_type == COM_IF_MODEM_CARD || - iod.if_type == COM_IF_RSA98III || - isa_get_vendorid(dev)) { - port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, - if_16550a_type[iod.if_type & 0x0f].iatsz, RF_ACTIVE); - } else { - port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, - if_16550a_type[iod.if_type & 0x0f].iat, - if_16550a_type[iod.if_type & 0x0f].iatsz, RF_ACTIVE); - } -#else - port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, - IO_COMSIZE, RF_ACTIVE); -#endif - if (!port) - return (ENXIO); -#ifdef PC98 - if (!IS_8251(iod.if_type)) { - if (isa_load_resourcev(port, - if_16550a_type[iod.if_type & 0x0f].iat, - if_16550a_type[iod.if_type & 0x0f].iatsz) != 0) { - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return ENXIO; - } - } -#endif - - com = malloc(sizeof(*com), M_DEVBUF, M_NOWAIT | M_ZERO); - if (com == NULL) { - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return (ENOMEM); - } - device_set_softc(dev, com); - com->bst = rman_get_bustag(port); - com->bsh = rman_get_bushandle(port); -#ifdef PC98 - if (!IS_8251(iod.if_type) && rclk == 0) - rclk = if_16550a_type[iod.if_type & 0x0f].rclk; -#else - if (rclk == 0) - rclk = DEFAULT_RCLK; -#endif - com->rclk = rclk; - - while (sio_inited != 2) - if (atomic_cmpset_int(&sio_inited, 0, 1)) { - mtx_init(&sio_lock, sio_driver_name, NULL, - (comconsole != -1) ? - MTX_SPIN | MTX_QUIET : MTX_SPIN); - atomic_store_rel_int(&sio_inited, 2); - } - -#if 0 - /* - * XXX this is broken - when we are first called, there are no - * previously configured IO ports. We could hard code - * 0x3f8, 0x2f8, 0x3e8, 0x2e8 etc but that's probably worse. - * This code has been doing nothing since the conversion since - * "count" is zero the first time around. - */ - if (!already_init) { - /* - * Turn off MCR_IENABLE for all likely serial ports. An unused - * port with its MCR_IENABLE gate open will inhibit interrupts - * from any used port that shares the interrupt vector. - * XXX the gate enable is elsewhere for some multiports. - */ - device_t *devs; - int count, i, xioport; -#ifdef PC98 - int xiftype; -#endif - - devclass_get_devices(sio_devclass, &devs, &count); -#ifdef PC98 - for (i = 0; i < count; i++) { - xdev = devs[i]; - xioport = bus_get_resource_start(xdev, SYS_RES_IOPORT, 0); - xiftype = GET_IFTYPE(device_get_flags(xdev)); - if (device_is_enabled(xdev) && xioport > 0) { - if (IS_8251(xiftype)) - outb((xioport & 0xff00) | PC98SIO_cmd_port(xiftype & 0x0f), 0xf2); - else - outb(xioport + if_16550a_type[xiftype & 0x0f].iat[com_mcr], 0); - } - } -#else - for (i = 0; i < count; i++) { - xdev = devs[i]; - if (device_is_enabled(xdev) && - bus_get_resource(xdev, SYS_RES_IOPORT, 0, &xioport, - NULL) == 0) - outb(xioport + com_mcr, 0); - } -#endif - free(devs, M_TEMP); - already_init = TRUE; - } -#endif - - if (COM_LLCONSOLE(flags)) { - printf("sio%d: reserved for low-level i/o\n", - device_get_unit(dev)); - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - return (ENXIO); - } - -#ifdef PC98 - DELAY(10); - - /* - * If the port is i8251 UART (internal, B98_01) - */ - if (pc98_check_if_type(dev, &iod) == -1) { - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - return (ENXIO); - } - if (iod.irq > 0) - bus_set_resource(dev, SYS_RES_IRQ, 0, iod.irq, 1); - if (IS_8251(iod.if_type)) { - outb(iod.cmd, 0); - DELAY(10); - outb(iod.cmd, 0); - DELAY(10); - outb(iod.cmd, 0); - DELAY(10); - outb(iod.cmd, CMD8251_RESET); - DELAY(1000); /* for a while...*/ - outb(iod.cmd, 0xf2); /* MODE (dummy) */ - DELAY(10); - outb(iod.cmd, 0x01); /* CMD (dummy) */ - DELAY(1000); /* for a while...*/ - if (( inb(iod.sts) & STS8251_TxEMP ) == 0 ) { - result = (ENXIO); - } - 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); - result = isa_irq_pending() ? 0 : ENXIO; - 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. - */ - result = 0; - } - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - if (result) { - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - } - return result; - } -#endif /* PC98 */ - /* - * If the device is on a multiport card and has an AST/4 - * compatible interrupt control register, initialize this - * register and prepare to leave MCR_IENABLE clear in the mcr. - * Otherwise, prepare to set MCR_IENABLE in the mcr. - * Point idev to the device struct giving the correct id_irq. - * This is the struct for the master device if there is one. - */ - idev = dev; - mcr_image = MCR_IENABLE; -#ifdef COM_MULTIPORT - if (COM_ISMULTIPORT(flags)) { -#ifndef PC98 - Port_t xiobase; - u_long io; -#endif - - idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags)); - if (idev == NULL) { - printf("sio%d: master device %d not configured\n", - device_get_unit(dev), COM_MPMASTER(flags)); - idev = dev; - } -#ifndef PC98 - if (!COM_NOTAST4(flags)) { - if (bus_get_resource(idev, SYS_RES_IOPORT, 0, &io, - NULL) == 0) { - xiobase = io; - if (bus_get_resource(idev, SYS_RES_IRQ, 0, - NULL, NULL) == 0) - outb(xiobase + com_scr, 0x80); - else - outb(xiobase + com_scr, 0); - } - mcr_image = 0; - } -#endif - } -#endif /* COM_MULTIPORT */ - if (bus_get_resource(idev, SYS_RES_IRQ, 0, NULL, NULL) != 0) - mcr_image = 0; - - bzero(failures, sizeof failures); - iobase = rman_get_start(port); - -#ifdef PC98 - if (iod.if_type == COM_IF_RSA98III) { - mcr_image = 0; - - outb(iobase + rsa_msr, 0x04); - outb(iobase + rsa_frr, 0x00); - if ((inb(iobase + rsa_srr) & 0x36) != 0x36) { - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - return (ENXIO); - } - outb(iobase + rsa_ier, 0x00); - outb(iobase + rsa_frr, 0x00); - outb(iobase + rsa_tivsr, 0x00); - outb(iobase + rsa_tcr, 0x00); - } - - tmp = if_16550a_type[iod.if_type & 0x0f].irr_write; - if (tmp != -1) { - /* MC16550II */ - int irqout; - switch (isa_get_irq(idev)) { - case 3: irqout = 4; break; - case 5: irqout = 5; break; - case 6: irqout = 6; break; - case 12: irqout = 7; break; - default: - printf("sio%d: irq configuration error\n", - device_get_unit(dev)); - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - return (ENXIO); - } - outb((iobase & 0x00ff) | tmp, irqout); - } -#endif - - /* - * We don't want to get actual interrupts, just masked ones. - * Interrupts from this line should already be masked in the ICU, - * but mask them in the processor as well in case there are some - * (misconfigured) shared interrupts. - */ - mtx_lock_spin(&sio_lock); -/* EXTRA DELAY? */ - - /* - * Initialize the speed and the word size and wait long enough to - * drain the maximum of 16 bytes of junk in device output queues. - * The speed is undefined after a master reset and must be set - * before relying on anything related to output. There may be - * junk after a (very fast) soft reboot and (apparently) after - * master reset. - * XXX what about the UART bug avoided by waiting in comparam()? - * We don't want to to wait long enough to drain at 2 bps. - */ - if (iobase == siocniobase) - DELAY((16 + 1) * 1000000 / (comdefaultrate / 10)); - else { - sio_setreg(com, com_cfcr, CFCR_DLAB | CFCR_8BITS); - divisor = siodivisor(rclk, SIO_TEST_SPEED); - sio_setreg(com, com_dlbl, divisor & 0xff); - sio_setreg(com, com_dlbh, divisor >> 8); - sio_setreg(com, com_cfcr, CFCR_8BITS); - DELAY((16 + 1) * 1000000 / (SIO_TEST_SPEED / 10)); - } - - /* - * Enable the interrupt gate and disable device interrupts. This - * should leave the device driving the interrupt line low and - * guarantee an edge trigger if an interrupt can be generated. - */ -/* EXTRA DELAY? */ - sio_setreg(com, com_mcr, mcr_image); - sio_setreg(com, com_ier, 0); - DELAY(1000); /* XXX */ - irqmap[0] = isa_irq_pending(); - - /* - * Attempt to set loopback mode so that we can send a null byte - * without annoying any external device. - */ -/* EXTRA DELAY? */ - sio_setreg(com, com_mcr, mcr_image | MCR_LOOPBACK); - - /* - * Attempt to generate an output interrupt. On 8250's, setting - * IER_ETXRDY generates an interrupt independent of the current - * setting and independent of whether the THR is empty. On 16450's, - * setting IER_ETXRDY generates an interrupt independent of the - * current setting. On 16550A's, setting IER_ETXRDY only - * generates an interrupt when IER_ETXRDY is not already set. - */ - sio_setreg(com, com_ier, IER_ETXRDY); -#ifdef PC98 - if (iod.if_type == COM_IF_RSA98III) - outb(iobase + rsa_ier, 0x04); -#endif - - /* - * On some 16x50 incompatibles, setting IER_ETXRDY doesn't generate - * an interrupt. They'd better generate one for actually doing - * output. Loopback may be broken on the same incompatibles but - * it's unlikely to do more than allow the null byte out. - */ - sio_setreg(com, com_data, 0); - if (iobase == siocniobase) - DELAY((1 + 2) * 1000000 / (comdefaultrate / 10)); - else - DELAY((1 + 2) * 1000000 / (SIO_TEST_SPEED / 10)); - - /* - * Turn off loopback mode so that the interrupt gate works again - * (MCR_IENABLE was hidden). This should leave the device driving - * an interrupt line high. It doesn't matter if the interrupt - * line oscillates while we are not looking at it, since interrupts - * are disabled. - */ -/* EXTRA DELAY? */ - sio_setreg(com, com_mcr, mcr_image); - - /* - * It seems my Xircom CBEM56G Cardbus modem wants to be reset - * to 8 bits *again*, or else probe test 0 will fail. - * gwk@sgi.com, 4/19/2001 - */ - sio_setreg(com, com_cfcr, CFCR_8BITS); - - /* - * Some PCMCIA cards (Palido 321s, DC-1S, ...) have the "TXRDY bug", - * so we probe for a buggy IIR_TXRDY implementation even in the - * noprobe case. We don't probe for it in the !noprobe case because - * noprobe is always set for PCMCIA cards and the problem is not - * known to affect any other cards. - */ - if (noprobe) { - /* Read IIR a few times. */ - for (fn = 0; fn < 2; fn ++) { - DELAY(10000); - failures[6] = sio_getreg(com, com_iir); - } - - /* IIR_TXRDY should be clear. Is it? */ - result = 0; - if (failures[6] & IIR_TXRDY) { - /* - * No. We seem to have the bug. Does our fix for - * it work? - */ - sio_setreg(com, com_ier, 0); - if (sio_getreg(com, com_iir) & IIR_NOPEND) { - /* Yes. We discovered the TXRDY bug! */ - SET_FLAG(dev, COM_C_IIR_TXRDYBUG); - } else { - /* No. Just fail. XXX */ - result = ENXIO; - sio_setreg(com, com_mcr, 0); - } - } else { - /* Yes. No bug. */ - CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); - } - sio_setreg(com, com_ier, 0); - sio_setreg(com, com_cfcr, CFCR_8BITS); - mtx_unlock_spin(&sio_lock); - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - if (iobase == siocniobase) - result = 0; - if (result != 0) { - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - } - return (result); - } - - /* - * Check that - * o the CFCR, IER and MCR in UART hold the values written to them - * (the values happen to be all distinct - this is good for - * avoiding false positive tests from bus echoes). - * o an output interrupt is generated and its vector is correct. - * o the interrupt goes away when the IIR in the UART is read. - */ -/* EXTRA DELAY? */ - failures[0] = sio_getreg(com, com_cfcr) - CFCR_8BITS; - failures[1] = sio_getreg(com, com_ier) - IER_ETXRDY; - failures[2] = sio_getreg(com, com_mcr) - mcr_image; - DELAY(10000); /* Some internal modems need this time */ - irqmap[1] = isa_irq_pending(); - failures[4] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_TXRDY; -#ifdef PC98 - if (iod.if_type == COM_IF_RSA98III) - inb(iobase + rsa_srr); -#endif - DELAY(1000); /* XXX */ - irqmap[2] = isa_irq_pending(); - failures[6] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND; -#ifdef PC98 - if (iod.if_type == COM_IF_RSA98III) - inb(iobase + rsa_srr); -#endif - - /* - * Turn off all device interrupts and check that they go off properly. - * Leave MCR_IENABLE alone. For ports without a master port, it gates - * the OUT2 output of the UART to - * the ICU input. Closing the gate would give a floating ICU input - * (unless there is another device driving it) and spurious interrupts. - * (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.) - */ - sio_setreg(com, com_ier, 0); - sio_setreg(com, com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */ - failures[7] = sio_getreg(com, com_ier); -#ifdef PC98 - if (iod.if_type == COM_IF_RSA98III) - outb(iobase + rsa_ier, 0x00); -#endif - DELAY(1000); /* XXX */ - irqmap[3] = isa_irq_pending(); - failures[9] = (sio_getreg(com, com_iir) & IIR_IMASK) - IIR_NOPEND; -#ifdef PC98 - if (iod.if_type == COM_IF_RSA98III) { - inb(iobase + rsa_srr); - outb(iobase + rsa_frr, 0x00); - } -#endif - - mtx_unlock_spin(&sio_lock); - - irqs = irqmap[1] & ~irqmap[0]; - if (bus_get_resource(idev, SYS_RES_IRQ, 0, &xirq, NULL) == 0 && - ((1 << xirq) & irqs) == 0) { - printf( - "sio%d: configured irq %ld not in bitmap of probed irqs %#x\n", - device_get_unit(dev), xirq, irqs); - printf( - "sio%d: port may not be enabled\n", - device_get_unit(dev)); - } - if (bootverbose) - printf("sio%d: irq maps: %#x %#x %#x %#x\n", - device_get_unit(dev), - irqmap[0], irqmap[1], irqmap[2], irqmap[3]); - - result = 0; - for (fn = 0; fn < sizeof failures; ++fn) - if (failures[fn]) { - sio_setreg(com, com_mcr, 0); - result = ENXIO; - if (bootverbose) { - printf("sio%d: probe failed test(s):", - device_get_unit(dev)); - for (fn = 0; fn < sizeof failures; ++fn) - if (failures[fn]) - printf(" %d", fn); - printf("\n"); - } - break; - } - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - if (iobase == siocniobase) - result = 0; - if (result != 0) { - device_set_softc(dev, NULL); - free(com, M_DEVBUF); - } - return (result); -} - -#ifdef COM_ESP -static int -espattach(com, esp_port) - struct com_s *com; - Port_t esp_port; -{ - u_char dips; - u_char val; - - /* - * Check the ESP-specific I/O port to see if we're an ESP - * card. If not, return failure immediately. - */ - if ((inb(esp_port) & 0xf3) == 0) { - printf(" port 0x%x is not an ESP board?\n", esp_port); - return (0); - } - - /* - * We've got something that claims to be a Hayes ESP card. - * Let's hope so. - */ - - /* 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 ((rman_get_start(com->ioportres) & 0xff) == - likely_com_ports[dips & 0x03]) -#else - if (rman_get_start(com->ioportres) == likely_com_ports[dips & 0x03]) -#endif - printf(" : ESP"); - else { - printf(" esp_port has com %d\n", dips & 0x03); - return (0); - } - - /* - * 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); - } - - /* - * Check for ability to emulate 16550: bit 7 == 1 - */ - if ((dips & 0x80) == 0) { - printf(" slave"); - return (0); - } - - /* - * Okay, we seem to be a Hayes ESP card. Whee. - */ - com->esp = TRUE; - com->esp_port = esp_port; - return (1); -} -#endif /* COM_ESP */ - -int -sioattach(dev, xrid, rclk) - device_t dev; - int xrid; - u_long rclk; -{ - struct com_s *com; -#ifdef COM_ESP - Port_t *espp; -#endif - Port_t iobase; - int unit; - u_int flags; - int rid; - struct resource *port; - int ret; - int error; - struct tty *tp; -#ifdef PC98 - u_char *obuf; - u_long obufsize; - int if_type = GET_IFTYPE(device_get_flags(dev)); -#endif - - rid = xrid; -#ifdef PC98 - if (IS_8251(if_type)) { - port = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, - RF_ACTIVE); - } else if (if_type == COM_IF_MODEM_CARD || - if_type == COM_IF_RSA98III || - isa_get_vendorid(dev)) { - port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, - if_16550a_type[if_type & 0x0f].iatsz, RF_ACTIVE); - } else { - port = isa_alloc_resourcev(dev, SYS_RES_IOPORT, &rid, - if_16550a_type[if_type & 0x0f].iat, - if_16550a_type[if_type & 0x0f].iatsz, RF_ACTIVE); - } -#else - port = bus_alloc_resource_anywhere(dev, SYS_RES_IOPORT, &rid, - IO_COMSIZE, RF_ACTIVE); -#endif - if (!port) - return (ENXIO); -#ifdef PC98 - if (!IS_8251(if_type)) { - if (isa_load_resourcev(port, - if_16550a_type[if_type & 0x0f].iat, - if_16550a_type[if_type & 0x0f].iatsz) != 0) { - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return ENXIO; - } - } -#endif - - iobase = rman_get_start(port); - unit = device_get_unit(dev); - com = device_get_softc(dev); - flags = device_get_flags(dev); - - if (unit >= sio_numunits) - sio_numunits = unit + 1; - -#ifdef PC98 - obufsize = 256; - if (if_type == COM_IF_RSA98III) - obufsize = 2048; - if ((obuf = malloc(obufsize * 2, M_DEVBUF, M_NOWAIT)) == NULL) { - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return ENXIO; - } - bzero(obuf, obufsize * 2); -#endif - - /* - * sioprobe() has initialized the device registers as follows: - * o cfcr = CFCR_8BITS. - * It is most important that CFCR_DLAB is off, so that the - * data port is not hidden when we enable interrupts. - * o ier = 0. - * Interrupts are only enabled when the line is open. - * o mcr = MCR_IENABLE, or 0 if the port has AST/4 compatible - * interrupt control register or the config specifies no irq. - * Keeping MCR_DTR and MCR_RTS off might stop the external - * device from sending before we are ready. - */ - bzero(com, sizeof *com); - com->unit = unit; - com->ioportres = port; - com->ioportrid = rid; - com->bst = rman_get_bustag(port); - com->bsh = rman_get_bushandle(port); - com->cfcr_image = CFCR_8BITS; - com->loses_outints = COM_LOSESOUTINTS(flags) != 0; - com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0; - com->tx_fifo_size = 1; -#ifdef PC98 - com->obufsize = obufsize; - com->obuf1 = obuf; - com->obuf2 = obuf + obufsize; -#endif - com->obufs[0].l_head = com->obuf1; - com->obufs[1].l_head = com->obuf2; - -#ifdef PC98 - com->pc98_if_type = if_type; - - if (IS_8251(if_type)) { - pc98_set_ioport(com); - - if (if_type == COM_IF_INTERNAL && pc98_check_8251fifo()) { - com->pc98_8251fifo = 1; - com->pc98_8251fifo_enable = 0; - } - } else { - bus_addr_t *iat = if_16550a_type[if_type & 0x0f].iat; - - com->data_port = iobase + iat[com_data]; - com->int_ctl_port = iobase + iat[com_ier]; - com->int_id_port = iobase + iat[com_iir]; - com->modem_ctl_port = iobase + iat[com_mcr]; - com->mcr_image = inb(com->modem_ctl_port); - com->line_status_port = iobase + iat[com_lsr]; - com->modem_status_port = iobase + iat[com_msr]; - } -#else /* not PC98 */ - com->data_port = iobase + com_data; - com->int_ctl_port = iobase + com_ier; - 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; -#endif - - tp = com->tp = ttyalloc(); - tp->t_oproc = comstart; - tp->t_param = comparam; - tp->t_stop = comstop; - tp->t_modem = commodem; - tp->t_break = combreak; - tp->t_close = comclose; - tp->t_open = comopen; - tp->t_sc = com; - -#ifdef PC98 - if (!IS_8251(if_type) && rclk == 0) - rclk = if_16550a_type[if_type & 0x0f].rclk; -#else - if (rclk == 0) - rclk = DEFAULT_RCLK; -#endif - com->rclk = rclk; - - if (unit == comconsole) - ttyconsolemode(tp, comdefaultrate); - error = siosetwater(com, tp->t_init_in.c_ispeed); - mtx_unlock_spin(&sio_lock); - if (error) { - /* - * Leave i/o resources allocated if this is a `cn'-level - * console, so that other devices can't snarf them. - */ - if (iobase != siocniobase) - bus_release_resource(dev, SYS_RES_IOPORT, rid, port); - return (ENOMEM); - } - - /* attempt to determine UART type */ - printf("sio%d: type", unit); - -#ifndef PC98 - if (!COM_ISMULTIPORT(flags) && - !COM_IIR_TXRDYBUG(flags) && !COM_NOSCR(flags)) { - u_char scr; - u_char scr1; - u_char scr2; - - scr = sio_getreg(com, com_scr); - sio_setreg(com, com_scr, 0xa5); - scr1 = sio_getreg(com, com_scr); - sio_setreg(com, com_scr, 0x5a); - scr2 = sio_getreg(com, com_scr); - sio_setreg(com, com_scr, scr); - if (scr1 != 0xa5 || scr2 != 0x5a) { - printf(" 8250 or not responding"); - goto determined_type; - } - } -#endif /* !PC98 */ -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) { - if (com->pc98_8251fifo && !COM_NOFIFO(flags)) - com->tx_fifo_size = 16; - com_int_TxRx_disable( com ); - com_cflag_and_speed_set( com, tp->t_init_in.c_cflag, comdefaultrate ); - com_tiocm_bic( com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE ); - com_send_break_off( com ); - - if (com->pc98_if_type == COM_IF_INTERNAL) { - printf(" (internal%s%s)", - com->pc98_8251fifo ? " fifo" : "", - PC98SIO_baud_rate_port(com->pc98_if_type) != -1 ? - " v-fast" : ""); - } else { - printf(" 8251%s", if_8251_type[com->pc98_if_type & 0x0f].name); - } - } else { -#endif /* PC98 */ - sio_setreg(com, com_fifo, FIFO_ENABLE | FIFO_RX_HIGH); - DELAY(100); - switch (inb(com->int_id_port) & IIR_FIFO_MASK) { - case FIFO_RX_LOW: - printf(" 16450"); - break; - case FIFO_RX_MEDL: - printf(" 16450?"); - break; - case FIFO_RX_MEDH: - printf(" 16550?"); - break; - case FIFO_RX_HIGH: - if (COM_NOFIFO(flags)) { - printf(" 16550A fifo disabled"); - break; - } - com->hasfifo = TRUE; -#ifdef PC98 - if (com->pc98_if_type == COM_IF_RSA98III) { - com->tx_fifo_size = 2048; - com->rsabase = iobase; - outb(com->rsabase + rsa_ier, 0x00); - outb(com->rsabase + rsa_frr, 0x00); - } -#else - if (COM_ST16650A(flags)) { - printf(" ST16650A"); - com->st16650a = TRUE; - com->tx_fifo_size = 32; - break; - } - if (COM_TI16754(flags)) { - printf(" TI16754"); - com->tx_fifo_size = 64; - break; - } -#endif - printf(" 16550A"); -#ifdef COM_ESP -#ifdef PC98 - if (com->pc98_if_type == COM_IF_ESP98) -#endif - for (espp = likely_esp_ports; *espp != 0; espp++) - if (espattach(com, *espp)) { - com->tx_fifo_size = 1024; - break; - } - if (com->esp) - break; -#endif -#ifdef PC98 - com->tx_fifo_size = 16; -#else - com->tx_fifo_size = COM_FIFOSIZE(flags); - if (com->tx_fifo_size == 0) - com->tx_fifo_size = 16; - else - printf(" lookalike with %u bytes FIFO", - com->tx_fifo_size); -#endif - break; - } - -#ifdef PC98 - if (com->pc98_if_type == COM_IF_RSB3000) { - /* Set RSB-2000/3000 Extended Buffer mode. */ - u_char lcr; - lcr = sio_getreg(com, com_cfcr); - sio_setreg(com, com_cfcr, lcr | CFCR_DLAB); - sio_setreg(com, com_emr, EMR_EXBUFF | EMR_EFMODE); - sio_setreg(com, com_cfcr, lcr); - } -#endif - -#ifdef COM_ESP - if (com->esp) { - /* - * Set 16550 compatibility mode. - * We don't use the ESP_MODE_SCALE bit to increase the - * fifo trigger levels because we can't handle large - * 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 */ - sio_setreg(com, com_fifo, 0); -#ifdef PC98 - printf("%s", if_16550a_type[com->pc98_if_type & 0x0f].name); -#else -determined_type: ; -#endif - -#ifdef COM_MULTIPORT - if (COM_ISMULTIPORT(flags)) { - device_t masterdev; - - com->multiport = TRUE; - printf(" (multiport"); - if (unit == COM_MPMASTER(flags)) - printf(" master"); - printf(")"); - masterdev = devclass_get_device(sio_devclass, - COM_MPMASTER(flags)); - com->no_irq = (masterdev == NULL || bus_get_resource(masterdev, - SYS_RES_IRQ, 0, NULL, NULL) != 0); - } -#endif /* COM_MULTIPORT */ -#ifdef PC98 - } -#endif - if (unit == comconsole) - printf(", console"); - if (COM_IIR_TXRDYBUG(flags)) - printf(" with a buggy IIR_TXRDY implementation"); - printf("\n"); - - if (sio_fast_ih == NULL) { - swi_add(&tty_intr_event, "sio", siopoll, NULL, SWI_TTY, 0, - &sio_fast_ih); - swi_add(&clk_intr_event, "sio", siopoll, NULL, SWI_CLOCK, 0, - &sio_slow_ih); - } - - com->flags = flags; - com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; - tp->t_pps = &com->pps; - - if (COM_PPSCTS(flags)) - com->pps_bit = MSR_CTS; - else - com->pps_bit = MSR_DCD; - pps_init(&com->pps); - - rid = 0; - com->irqres = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); - if (com->irqres) { - ret = bus_setup_intr(dev, com->irqres, - INTR_TYPE_TTY, - siointr, NULL, com, &com->cookie); - if (ret) { - ret = bus_setup_intr(dev, - com->irqres, INTR_TYPE_TTY, - NULL, (driver_intr_t *)siointr, - com, &com->cookie); - if (ret == 0) - device_printf(dev, "unable to activate interrupt in fast mode - using normal mode\n"); - } - if (ret) - device_printf(dev, "could not activate interrupt\n"); -#if defined(KDB) - /* - * Enable interrupts for early break-to-debugger support - * on the console. - */ - if (ret == 0 && unit == comconsole) - outb(siocniobase + com_ier, IER_ERXRDY | IER_ERLS | - IER_EMSC); -#endif - } - - /* We're ready, open the doors... */ - ttycreate(tp, TS_CALLOUT, "d%r", unit); - - return (0); -} - -static int -comopen(struct tty *tp, struct cdev *dev) -{ - struct com_s *com; - int i; - - com = tp->t_sc; - com->poll = com->no_irq; - com->poll_output = com->loses_outints; -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) { - com_tiocm_bis(com, TIOCM_DTR|TIOCM_RTS); - pc98_msrint_start(dev); - if (com->pc98_8251fifo) { - com->pc98_8251fifo_enable = 1; - outb(I8251F_fcr, - FIFO_ENABLE | FIFO_XMT_RST | FIFO_RCV_RST); - } - } -#endif - if (com->hasfifo) { - /* - * (Re)enable and drain fifos. - * - * Certain SMC chips cause problems if the fifos - * are enabled while input is ready. Turn off the - * fifo if necessary to clear the input. We test - * the input ready bit after enabling the fifos - * since we've already enabled them in comparam() - * and to handle races between enabling and fresh - * input. - */ - for (i = 0; i < 500; i++) { - sio_setreg(com, com_fifo, - FIFO_RCV_RST | FIFO_XMT_RST | com->fifo_image); -#ifdef PC98 - if (com->pc98_if_type == COM_IF_RSA98III) - outb(com->rsabase + rsa_frr , 0x00); -#endif - /* - * XXX the delays are for superstitious - * historical reasons. It must be less than - * the character time at the maximum - * supported speed (87 usec at 115200 bps - * 8N1). Otherwise we might loop endlessly - * if data is streaming in. We used to use - * delays of 100. That usually worked - * because DELAY(100) used to usually delay - * for about 85 usec instead of 100. - */ - DELAY(50); -#ifdef PC98 - if (com->pc98_if_type == COM_IF_RSA98III ? - !(inb(com->rsabase + rsa_srr) & 0x08) : - !(inb(com->line_status_port) & LSR_RXRDY)) - break; -#else - if (!(inb(com->line_status_port) & LSR_RXRDY)) - break; -#endif - sio_setreg(com, com_fifo, 0); - DELAY(50); - (void) inb(com->data_port); - } - if (i == 500) - return (EIO); - } - - mtx_lock_spin(&sio_lock); -#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); - } else { -#endif - (void) inb(com->line_status_port); - (void) inb(com->data_port); - com->prev_modem_status = com->last_modem_status - = inb(com->modem_status_port); - outb(com->int_ctl_port, - IER_ERXRDY | IER_ERLS | IER_EMSC - | (COM_IIR_TXRDYBUG(com->flags) ? 0 : IER_ETXRDY)); -#ifdef PC98 - if (com->pc98_if_type == COM_IF_RSA98III) { - outb(com->rsabase + rsa_ier, 0x1d); - outb(com->int_ctl_port, IER_ERLS | IER_EMSC); - } -#endif -#ifdef PC98 - } -#endif - mtx_unlock_spin(&sio_lock); - siosettimeout(); - /* XXX: should be generic ? */ -#ifdef PC98 - if ((IS_8251(com->pc98_if_type) && - (pc98_get_modem_status(com) & TIOCM_CAR)) || - (!IS_8251(com->pc98_if_type) && - (com->prev_modem_status & MSR_DCD)) || - ISCALLOUT(dev)) - ttyld_modem(tp, 1); -#else - if (com->prev_modem_status & MSR_DCD || ISCALLOUT(dev)) - ttyld_modem(tp, 1); -#endif - return (0); -} - -static void -comclose(tp) - struct tty *tp; -{ - int s; - struct com_s *com; - - s = spltty(); - com = tp->t_sc; - com->poll = FALSE; - com->poll_output = FALSE; -#ifdef PC98 - com_send_break_off(com); -#else - sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK); -#endif - -#if defined(KDB) - /* - * Leave interrupts enabled and don't clear DTR if this is the - * console. This allows us to detect break-to-debugger events - * while the console device is closed. - */ - if (com->unit != comconsole) -#endif - { -#ifdef PC98 - int tmp; - if (IS_8251(com->pc98_if_type)) - com_int_TxRx_disable(com); - else - sio_setreg(com, com_ier, 0); - if (com->pc98_if_type == COM_IF_RSA98III) - outb(com->rsabase + rsa_ier, 0x00); - if (IS_8251(com->pc98_if_type)) - tmp = pc98_get_modem_status(com) & TIOCM_CAR; - else - tmp = com->prev_modem_status & MSR_DCD; -#else - sio_setreg(com, com_ier, 0); -#endif - if (tp->t_cflag & HUPCL - /* - * XXX we will miss any carrier drop between here and the - * next open. Perhaps we should watch DCD even when the - * port is closed; it is not sufficient to check it at - * the next open because it might go up and down while - * we're not watching. - */ - || (!tp->t_actout -#ifdef PC98 - && !(tmp) -#else - && !(com->prev_modem_status & MSR_DCD) -#endif - && !(tp->t_init_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); - else -#endif - (void)commodem(tp, 0, SER_DTR); - ttydtrwaitstart(tp); - } -#ifdef PC98 - else { - if (IS_8251(com->pc98_if_type)) - com_tiocm_bic(com, TIOCM_LE); - } -#endif - } -#ifdef PC98 - if (com->pc98_8251fifo) { - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, FIFO_XMT_RST | FIFO_RCV_RST); - com->pc98_8251fifo_enable = 0; - } -#endif - if (com->hasfifo) { - /* - * Disable fifos so that they are off after controlled - * reboots. Some BIOSes fail to detect 16550s when the - * fifos are enabled. - */ - sio_setreg(com, com_fifo, 0); - } - tp->t_actout = FALSE; - wakeup(&tp->t_actout); - wakeup(TSA_CARR_ON(tp)); /* restart any wopeners */ - siosettimeout(); - splx(s); -} - -static void -siobusycheck(chan) - void *chan; -{ - struct com_s *com; - int s; - - com = (struct com_s *)chan; - - /* - * Clear TS_BUSY if low-level output is complete. - * spl locking is sufficient because siointr1() does not set CS_BUSY. - * If siointr1() clears CS_BUSY after we look at it, then we'll get - * called again. Reading the line status port outside of siointr1() - * is safe because CS_BUSY is clear so there are no output interrupts - * to lose. - */ - s = spltty(); - if (com->state & CS_BUSY) - com->extra_state &= ~CSE_BUSYCHECK; /* False alarm. */ -#ifdef PC98 - else if ((IS_8251(com->pc98_if_type) && - ((com->pc98_8251fifo_enable && - (inb(I8251F_lsr) & (FLSR_TxRDY | FLSR_TxEMP)) - == (FLSR_TxRDY | FLSR_TxEMP)) || - (!com->pc98_8251fifo_enable && - (inb(com->sts_port) & (STS8251_TxRDY | STS8251_TxEMP)) - == (STS8251_TxRDY | STS8251_TxEMP)))) || - ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY)) - == (LSR_TSRE | LSR_TXRDY))) { -#else - else if ((inb(com->line_status_port) & (LSR_TSRE | LSR_TXRDY)) - == (LSR_TSRE | LSR_TXRDY)) { -#endif - com->tp->t_state &= ~TS_BUSY; - ttwwakeup(com->tp); - com->extra_state &= ~CSE_BUSYCHECK; - } else - timeout(siobusycheck, com, hz / 100); - splx(s); -} - -static u_int -siodivisor(rclk, speed) - u_long rclk; - speed_t speed; -{ - long actual_speed; - u_int divisor; - int error; - - if (speed == 0) - return (0); -#if UINT_MAX > (ULONG_MAX - 1) / 8 - if (speed > (ULONG_MAX - 1) / 8) - return (0); -#endif - divisor = (rclk / (8UL * speed) + 1) / 2; - if (divisor == 0 || divisor >= 65536) - return (0); - actual_speed = rclk / (16UL * divisor); - - /* 10 times error in percent: */ - error = ((actual_speed - (long)speed) * 2000 / (long)speed + 1) / 2; - - /* 3.0% maximum error tolerance: */ - if (error < -30 || error > 30) - return (0); - - return (divisor); -} - -/* - * Call this function with the sio_lock mutex held. It will return with the - * lock still held. - */ -static void -sioinput(com) - struct com_s *com; -{ - u_char *buf; - int incc; - u_char line_status; - int recv_data; - struct tty *tp; - - buf = com->ibuf; - tp = com->tp; - if (!(tp->t_state & TS_ISOPEN) || !(tp->t_cflag & CREAD)) { - com_events -= (com->iptr - com->ibuf); - com->iptr = com->ibuf; - return; - } - if (tp->t_state & TS_CAN_BYPASS_L_RINT) { - /* - * Avoid the grotesquely inefficient lineswitch routine - * (ttyinput) in "raw" mode. It usually takes about 450 - * instructions (that's without canonical processing or echo!). - * slinput is reasonably fast (usually 40 instructions plus - * call overhead). - */ - do { - /* - * This may look odd, but it is using save-and-enable - * semantics instead of the save-and-disable semantics - * that are used everywhere else. - */ - mtx_unlock_spin(&sio_lock); - incc = com->iptr - buf; - if (tp->t_rawq.c_cc + incc > tp->t_ihiwat - && (com->state & CS_RTS_IFLOW - || tp->t_iflag & IXOFF) - && !(tp->t_state & TS_TBLOCK)) - ttyblock(tp); - com->delta_error_counts[CE_TTY_BUF_OVERFLOW] - += b_to_q((char *)buf, incc, &tp->t_rawq); - buf += incc; - tk_nin += incc; - tk_rawcc += incc; - tp->t_rawcc += incc; - ttwakeup(tp); - if (tp->t_state & TS_TTSTOP - && (tp->t_iflag & IXANY - || tp->t_cc[VSTART] == tp->t_cc[VSTOP])) { - tp->t_state &= ~TS_TTSTOP; - tp->t_lflag &= ~FLUSHO; - comstart(tp); - } - mtx_lock_spin(&sio_lock); - } while (buf < com->iptr); - } else { - do { - /* - * This may look odd, but it is using save-and-enable - * semantics instead of the save-and-disable semantics - * that are used everywhere else. - */ - mtx_unlock_spin(&sio_lock); - line_status = buf[com->ierroff]; - recv_data = *buf++; - if (line_status - & (LSR_BI | LSR_FE | LSR_OE | LSR_PE)) { - if (line_status & LSR_BI) - recv_data |= TTY_BI; - if (line_status & LSR_FE) - recv_data |= TTY_FE; - if (line_status & LSR_OE) - recv_data |= TTY_OE; - if (line_status & LSR_PE) - recv_data |= TTY_PE; - } - ttyld_rint(tp, recv_data); - mtx_lock_spin(&sio_lock); - } while (buf < com->iptr); - } - com_events -= (com->iptr - com->ibuf); - com->iptr = com->ibuf; - - /* - * There is now room for another low-level buffer full of input, - * so enable RTS if it is now disabled and there is room in the - * high-level buffer. - */ -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) { - if ((com->state & CS_RTS_IFLOW) && - !(com_tiocm_get(com) & TIOCM_RTS) && - !(tp->t_state & TS_TBLOCK)) - com_tiocm_bis(com, TIOCM_RTS); - } else { - if ((com->state & CS_RTS_IFLOW) && - !(com->mcr_image & MCR_RTS) && - !(tp->t_state & TS_TBLOCK)) - outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); - } -#else - if ((com->state & CS_RTS_IFLOW) && !(com->mcr_image & MCR_RTS) && - !(tp->t_state & TS_TBLOCK)) - outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); -#endif -} - -static int -siointr(arg) - void *arg; -{ - struct com_s *com; -#if defined(PC98) && defined(COM_MULTIPORT) - u_char rsa_buf_status; -#endif - -#ifndef COM_MULTIPORT - com = (struct com_s *)arg; - - mtx_lock_spin(&sio_lock); - siointr1(com); - mtx_unlock_spin(&sio_lock); -#else /* COM_MULTIPORT */ - bool_t possibly_more_intrs; - int unit; - - /* - * Loop until there is no activity on any port. This is necessary - * to get an interrupt edge more than to avoid another interrupt. - * If the IRQ signal is just an OR of the IRQ signals from several - * devices, then the edge from one may be lost because another is - * on. - */ - mtx_lock_spin(&sio_lock); - do { - possibly_more_intrs = FALSE; - for (unit = 0; unit < sio_numunits; ++unit) { - com = com_addr(unit); - /* - * XXX COM_LOCK(); - * would it work here, or be counter-productive? - */ -#ifdef PC98 - if (com != NULL - && !com->gone - && IS_8251(com->pc98_if_type)) { - siointr1(com); - } else 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) - != IIR_NOPEND) { - siointr1(com); - possibly_more_intrs = TRUE; - } - /* XXX COM_UNLOCK(); */ - } - } while (possibly_more_intrs); - mtx_unlock_spin(&sio_lock); -#endif /* COM_MULTIPORT */ - return (FILTER_HANDLED); -} - -static struct timespec siots[8]; -static int siotso; -static int volatile siotsunit = -1; - -static int -sysctl_siots(SYSCTL_HANDLER_ARGS) -{ - char buf[128]; - long long delta; - size_t len; - int error, i, tso; - - for (i = 1, tso = siotso; i < tso; i++) { - delta = (long long)(siots[i].tv_sec - siots[i - 1].tv_sec) * - 1000000000 + - (siots[i].tv_nsec - siots[i - 1].tv_nsec); - len = sprintf(buf, "%lld\n", delta); - if (delta >= 110000) - len += sprintf(buf + len - 1, ": *** %ld.%09ld\n", - (long)siots[i].tv_sec, siots[i].tv_nsec) - 1; - if (i == tso - 1) - buf[len - 1] = '\0'; - error = SYSCTL_OUT(req, buf, len); - if (error != 0) - return (error); - } - return (0); -} - -SYSCTL_PROC(_machdep, OID_AUTO, siots, CTLTYPE_STRING | CTLFLAG_RD, - 0, 0, sysctl_siots, "A", "sio timestamps"); - -static void -siointr1(com) - struct com_s *com; -{ - u_char int_ctl; - u_char int_ctl_new; - u_char line_status; - u_char modem_status; - u_char *ioptr; - u_char recv_data; -#ifdef PC98 - u_char tmp = 0; - u_char rsa_buf_status = 0; - int rsa_tx_fifo_size = 0; -#endif /* PC98 */ -#if defined(KDB) - int kdb_brk; - -again: -#endif - - if (COM_IIR_TXRDYBUG(com->flags)) { - int_ctl = inb(com->int_ctl_port); - int_ctl_new = int_ctl; - } else { - int_ctl = 0; - int_ctl_new = 0; - } - - while (!com->gone) { -#ifdef PC98 -status_read:; - if (IS_8251(com->pc98_if_type)) { - if (com->pc98_8251fifo_enable) - tmp = inb(I8251F_lsr); - else - tmp = inb(com->sts_port); -more_intr: - line_status = 0; - if (com->pc98_8251fifo_enable) { - if (tmp & FLSR_TxRDY) line_status |= LSR_TXRDY; - if (tmp & FLSR_RxRDY) line_status |= LSR_RXRDY; - if (tmp & FLSR_TxEMP) line_status |= LSR_TSRE; - if (tmp & FLSR_PE) line_status |= LSR_PE; - if (tmp & FLSR_OE) line_status |= LSR_OE; - if (tmp & FLSR_BI) line_status |= LSR_BI; - } else { - if (tmp & STS8251_TxRDY) line_status |= LSR_TXRDY; - if (tmp & STS8251_RxRDY) line_status |= LSR_RXRDY; - if (tmp & STS8251_TxEMP) line_status |= LSR_TSRE; - if (tmp & STS8251_PE) line_status |= LSR_PE; - if (tmp & STS8251_OE) line_status |= LSR_OE; - if (tmp & STS8251_FE) line_status |= LSR_FE; - if (tmp & STS8251_BI) line_status |= LSR_BI; - } - } else { -#endif /* PC98 */ - if (com->pps.ppsparam.mode & PPS_CAPTUREBOTH) { - modem_status = inb(com->modem_status_port); - if ((modem_status ^ com->last_modem_status) & - com->pps_bit) { - pps_capture(&com->pps); - pps_event(&com->pps, - (modem_status & com->pps_bit) ? - PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); - } - } - 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 (com->pc98_8251fifo_enable) { - recv_data = inb(I8251F_data); - if (tmp & - (FLSR_PE | FLSR_OE | FLSR_BI)) { - pc98_i8251_or_cmd(com, CMD8251_ER); - recv_data = 0; - } - } else { - recv_data = inb(com->data_port); - if (tmp & (STS8251_PE | STS8251_OE | - STS8251_FE | STS8251_BI)) { - pc98_i8251_or_cmd(com, CMD8251_ER); - recv_data = 0; - } - } - } else 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 - recv_data = inb(com->data_port); -#ifdef KDB - if (com->unit == comconsole && - (kdb_brk = kdb_alt_break(recv_data, - &com->alt_brk_state)) != 0) { - goto again; - } -#endif /* KDB */ - if (line_status & (LSR_BI | LSR_FE | LSR_PE)) { - /* - * Don't store BI if IGNBRK or FE/PE if IGNPAR. - * Otherwise, push the work to a higher level - * (to handle PARMRK) if we're bypassing. - * Otherwise, convert BI/FE and PE+INPCK to 0. - * - * This makes bypassing work right in the - * usual "raw" case (IGNBRK set, and IGNPAR - * and INPCK clear). - * - * Note: BI together with FE/PE means just BI. - */ - if (line_status & LSR_BI) { -#if defined(KDB) - if (com->unit == comconsole) { - kdb_enter(KDB_WHY_BREAK, - "Line break on console"); - goto cont; - } -#endif - if (com->tp == NULL - || com->tp->t_iflag & IGNBRK) - goto cont; - } else { - if (com->tp == NULL - || com->tp->t_iflag & IGNPAR) - goto cont; - } - if (com->tp->t_state & TS_CAN_BYPASS_L_RINT - && (line_status & (LSR_BI | LSR_FE) - || com->tp->t_iflag & INPCK)) - recv_data = 0; - } - ++com->bytes_in; - if (com->tp != NULL && - com->tp->t_hotchar != 0 && recv_data == com->tp->t_hotchar) - swi_sched(sio_fast_ih, 0); - ioptr = com->iptr; - if (ioptr >= com->ibufend) - CE_RECORD(com, CE_INTERRUPT_BUF_OVERFLOW); - else { - if (com->tp != NULL && com->tp->t_do_timestamp) - microtime(&com->tp->t_timestamp); - ++com_events; - swi_sched(sio_slow_ih, SWI_DELAY); -#if 0 /* for testing input latency vs efficiency */ -if (com->iptr - com->ibuf == 8) - swi_sched(sio_fast_ih, 0); -#endif - ioptr[0] = recv_data; - ioptr[com->ierroff] = line_status; - com->iptr = ++ioptr; - if (ioptr == com->ihighwater - && com->state & CS_RTS_IFLOW) -#ifdef PC98 - IS_8251(com->pc98_if_type) ? - com_tiocm_bic(com, TIOCM_RTS) : -#endif - outb(com->modem_ctl_port, - com->mcr_image &= ~MCR_RTS); - if (line_status & LSR_OE) - CE_RECORD(com, CE_OVERRUN); - } -cont: - if (line_status & LSR_TXRDY - && com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) - goto txrdy; - - /* - * "& 0x7F" is to avoid the gcc-1.40 generating a slow - * jump from the top of the loop to here - */ -#ifdef PC98 - 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)) { -#endif - modem_status = inb(com->modem_status_port); - if (modem_status != com->last_modem_status) { - /* - * Schedule high level to handle DCD changes. Note - * that we don't use the delta bits anywhere. Some - * UARTs mess them up, and it's easy to remember the - * previous bits and calculate the delta. - */ - com->last_modem_status = modem_status; - if (!(com->state & CS_CHECKMSR)) { - com_events += LOTS_OF_EVENTS; - com->state |= CS_CHECKMSR; - swi_sched(sio_fast_ih, 0); - } - - /* handle CTS change immediately for crisp flow ctl */ - if (com->state & CS_CTS_OFLOW) { - if (modem_status & MSR_CTS) - com->state |= CS_ODEVREADY; - else - com->state &= ~CS_ODEVREADY; - } - } -#ifdef PC98 - } -#endif - -txrdy: - /* 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 -#ifdef PC98 - Port_t tmp_data_port; - - if (IS_8251(com->pc98_if_type) && - com->pc98_8251fifo_enable) - tmp_data_port = I8251F_data; - else - tmp_data_port = com->data_port; -#endif - - ioptr = com->obufq.l_head; - if (com->tx_fifo_size > 1 && com->unit != siotsunit) { - 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; - do -#ifdef PC98 - outb(tmp_data_port, *ioptr++); -#else - outb(com->data_port, *ioptr++); -#endif - while (--ocount != 0); - } else { -#ifdef PC98 - outb(tmp_data_port, *ioptr++); -#else - outb(com->data_port, *ioptr++); -#endif - ++com->bytes_out; - if (com->unit == siotsunit - && siotso < sizeof siots / sizeof siots[0]) - nanouptime(&siots[siotso++]); - } -#ifdef PC98 - 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; - if (COM_IIR_TXRDYBUG(com->flags)) - int_ctl_new = int_ctl | IER_ETXRDY; - if (ioptr >= com->obufq.l_tail) { - struct lbq *qp; - - qp = com->obufq.l_next; - qp->l_queued = FALSE; - qp = qp->l_next; - if (qp != NULL) { - com->obufq.l_head = qp->l_head; - com->obufq.l_tail = qp->l_tail; - com->obufq.l_next = qp; - } else { - /* output just completed */ - if (COM_IIR_TXRDYBUG(com->flags)) - int_ctl_new = int_ctl - & ~IER_ETXRDY; - com->state &= ~CS_BUSY; -#if defined(PC98) - if (IS_8251(com->pc98_if_type) && - pc98_check_i8251_interrupt(com) & IEN_TxFLAG) - com_int_Tx_disable(com); -#endif - } - if (!(com->state & CS_ODONE)) { - com_events += LOTS_OF_EVENTS; - com->state |= CS_ODONE; - /* handle at high level ASAP */ - swi_sched(sio_fast_ih, 0); - } - } -#ifdef PC98 - if (COM_IIR_TXRDYBUG(com->flags) - && int_ctl != int_ctl_new) { - if (com->pc98_if_type == COM_IF_RSA98III) { - int_ctl_new &= ~(IER_ETXRDY | IER_ERXRDY); - outb(com->int_ctl_port, int_ctl_new); - outb(com->rsabase + rsa_ier, 0x1d); - } else - outb(com->int_ctl_port, int_ctl_new); - } -#else - if (COM_IIR_TXRDYBUG(com->flags) - && int_ctl != int_ctl_new) - outb(com->int_ctl_port, int_ctl_new); -#endif - } -#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 (com->pc98_8251fifo_enable) { - if ((tmp = inb(I8251F_lsr)) & FLSR_RxRDY) - goto more_intr; - } else { - 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)) - return; -#endif - if ((inb(com->int_id_port) & IIR_IMASK) == IIR_NOPEND) -#endif /* COM_MULTIPORT */ - return; - } -} - -/* software interrupt handler for SWI_TTY */ -static void -siopoll(void *dummy) -{ - int unit; - - if (com_events == 0) - return; -repeat: - for (unit = 0; unit < sio_numunits; ++unit) { - struct com_s *com; - int incc; - struct tty *tp; - - com = com_addr(unit); - if (com == NULL) - continue; - tp = com->tp; - if (tp == NULL || com->gone) { - /* - * Discard any events related to never-opened or - * going-away devices. - */ - mtx_lock_spin(&sio_lock); - incc = com->iptr - com->ibuf; - com->iptr = com->ibuf; - if (com->state & CS_CHECKMSR) { - incc += LOTS_OF_EVENTS; - com->state &= ~CS_CHECKMSR; - } - com_events -= incc; - mtx_unlock_spin(&sio_lock); - continue; - } - if (com->iptr != com->ibuf) { - mtx_lock_spin(&sio_lock); - sioinput(com); - mtx_unlock_spin(&sio_lock); - } - if (com->state & CS_CHECKMSR) { - u_char delta_modem_status; - -#ifdef PC98 - if (!IS_8251(com->pc98_if_type)) { -#endif - mtx_lock_spin(&sio_lock); - delta_modem_status = com->last_modem_status - ^ com->prev_modem_status; - com->prev_modem_status = com->last_modem_status; - com_events -= LOTS_OF_EVENTS; - com->state &= ~CS_CHECKMSR; - mtx_unlock_spin(&sio_lock); - if (delta_modem_status & MSR_DCD) - ttyld_modem(tp, - com->prev_modem_status & MSR_DCD); -#ifdef PC98 - } -#endif - } - if (com->state & CS_ODONE) { - mtx_lock_spin(&sio_lock); - com_events -= LOTS_OF_EVENTS; - com->state &= ~CS_ODONE; - mtx_unlock_spin(&sio_lock); - if (!(com->state & CS_BUSY) - && !(com->extra_state & CSE_BUSYCHECK)) { - timeout(siobusycheck, com, hz / 100); - com->extra_state |= CSE_BUSYCHECK; - } - ttyld_start(tp); - } - if (com_events == 0) - break; - } - if (com_events >= LOTS_OF_EVENTS) - goto repeat; -} - -static void -combreak(tp, sig) - struct tty *tp; - int sig; -{ - struct com_s *com; - - com = tp->t_sc; - -#ifdef PC98 - if (sig) - com_send_break_on(com); - else - com_send_break_off(com); -#else - if (sig) - sio_setreg(com, com_cfcr, com->cfcr_image |= CFCR_SBREAK); - else - sio_setreg(com, com_cfcr, com->cfcr_image &= ~CFCR_SBREAK); -#endif -} - -static int -comparam(tp, t) - struct tty *tp; - struct termios *t; -{ - u_int cfcr; - int cflag; - struct com_s *com; - u_int divisor; - u_char dlbh; - u_char dlbl; - u_char efr_flowbits; - int s; -#ifdef PC98 - u_char param = 0; -#endif - - com = tp->t_sc; - if (com == NULL) - return (ENODEV); - -#ifdef PC98 - cfcr = 0; - - if (IS_8251(com->pc98_if_type)) { - if (pc98_ttspeedtab(com, t->c_ospeed, &divisor) != 0) - return (EINVAL); - } else { -#endif - /* check requested parameters */ - if (t->c_ispeed != (t->c_ospeed != 0 ? t->c_ospeed : tp->t_ospeed)) - return (EINVAL); - divisor = siodivisor(com->rclk, t->c_ispeed); - if (divisor == 0) - return (EINVAL); -#ifdef PC98 - } -#endif - - /* parameters are OK, convert them to the com struct and the device */ - s = spltty(); -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) { - if (t->c_ospeed == 0) - com_tiocm_bic(com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE); - else - com_tiocm_bis(com, TIOCM_DTR|TIOCM_RTS|TIOCM_LE); - } else -#endif - if (t->c_ospeed == 0) - (void)commodem(tp, 0, SER_DTR); /* hang up line */ - else - (void)commodem(tp, SER_DTR, 0); - cflag = t->c_cflag; -#ifdef PC98 - if (!IS_8251(com->pc98_if_type)) { -#endif - switch (cflag & CSIZE) { - case CS5: - cfcr = CFCR_5BITS; - break; - case CS6: - cfcr = CFCR_6BITS; - break; - case CS7: - cfcr = CFCR_7BITS; - break; - default: - cfcr = CFCR_8BITS; - break; - } - if (cflag & PARENB) { - cfcr |= CFCR_PENAB; - if (!(cflag & PARODD)) - cfcr |= CFCR_PEVEN; - } - if (cflag & CSTOPB) - cfcr |= CFCR_STOPB; - - if (com->hasfifo) { - /* - * Use a fifo trigger level low enough so that the input - * latency from the fifo is less than about 16 msec and - * the total latency is less than about 30 msec. These - * latencies are reasonable for humans. Serial comms - * protocols shouldn't expect anything better since modem - * latencies are larger. - * - * The fifo trigger level cannot be set at RX_HIGH for high - * speed connections without further work on reducing - * interrupt disablement times in other parts of the system, - * without producing silo overflow errors. - */ - com->fifo_image = com->unit == siotsunit ? 0 - : t->c_ispeed <= 4800 - ? FIFO_ENABLE : FIFO_ENABLE | FIFO_RX_MEDH; -#ifdef COM_ESP - /* - * The Hayes ESP card needs the fifo DMA mode bit set - * in compatibility mode. If not, it will interrupt - * for each character received. - */ - if (com->esp) - com->fifo_image |= FIFO_DMA_MODE; -#endif - sio_setreg(com, com_fifo, com->fifo_image); - } -#ifdef PC98 - } -#endif - - /* - * This returns with interrupts disabled so that we can complete - * the speed change atomically. Keeping interrupts disabled is - * especially important while com_data is hidden. - */ - (void) siosetwater(com, t->c_ispeed); - -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) - com_cflag_and_speed_set(com, cflag, t->c_ospeed); - else { -#endif - sio_setreg(com, com_cfcr, cfcr | CFCR_DLAB); - /* - * Only set the divisor registers if they would change, since on - * some 16550 incompatibles (UMC8669F), setting them while input - * is arriving loses sync until data stops arriving. - */ - dlbl = divisor & 0xFF; - if (sio_getreg(com, com_dlbl) != dlbl) - sio_setreg(com, com_dlbl, dlbl); - dlbh = divisor >> 8; - if (sio_getreg(com, com_dlbh) != dlbh) - sio_setreg(com, com_dlbh, dlbh); -#ifdef PC98 - } -#endif - - efr_flowbits = 0; - - if (cflag & CRTS_IFLOW) { - com->state |= CS_RTS_IFLOW; - efr_flowbits |= EFR_AUTORTS; - /* - * If CS_RTS_IFLOW just changed from off to on, the change - * needs to be propagated to MCR_RTS. This isn't urgent, - * so do it later by calling comstart() instead of repeating - * a lot of code from comstart() here. - */ - } else if (com->state & CS_RTS_IFLOW) { - com->state &= ~CS_RTS_IFLOW; - /* - * CS_RTS_IFLOW just changed from on to off. Force MCR_RTS - * on here, since comstart() won't do it later. - */ -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) - com_tiocm_bis(com, TIOCM_RTS); - else - outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); -#else - outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); -#endif - } - - /* - * Set up state to handle output flow control. - * XXX - worth handling MDMBUF (DCD) flow control at the lowest level? - * Now has 10+ msec latency, while CTS flow has 50- usec latency. - */ - 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; - efr_flowbits |= EFR_AUTOCTS; -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) { - if (!(pc98_get_modem_status(com) & TIOCM_CTS)) - com->state &= ~CS_ODEVREADY; - } else 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; - } - -#ifdef PC98 - if (!IS_8251(com->pc98_if_type)) - sio_setreg(com, com_cfcr, com->cfcr_image = cfcr); -#else - if (com->st16650a) { - sio_setreg(com, com_lcr, LCR_EFR_ENABLE); - sio_setreg(com, com_efr, - (sio_getreg(com, com_efr) - & ~(EFR_AUTOCTS | EFR_AUTORTS)) | efr_flowbits); - } - sio_setreg(com, com_cfcr, com->cfcr_image = cfcr); -#endif - - /* XXX shouldn't call functions while intrs are disabled. */ - ttyldoptim(tp); - - mtx_unlock_spin(&sio_lock); - splx(s); - comstart(tp); - if (com->ibufold != NULL) { - free(com->ibufold, M_DEVBUF); - com->ibufold = NULL; - } - return (0); -} - -/* - * This function must be called with the sio_lock mutex released and will - * return with it obtained. - */ -static int -siosetwater(com, speed) - struct com_s *com; - speed_t speed; -{ - int cp4ticks; - u_char *ibuf; - int ibufsize; - struct tty *tp; - - /* - * Make the buffer size large enough to handle a softtty interrupt - * latency of about 2 ticks without loss of throughput or data - * (about 3 ticks if input flow control is not used or not honoured, - * but a bit less for CS5-CS7 modes). - */ - cp4ticks = speed / 10 / hz * 4; - for (ibufsize = 128; ibufsize < cp4ticks;) - ibufsize <<= 1; -#ifdef PC98 - if (com->pc98_if_type == COM_IF_RSA98III) - ibufsize = 2048; -#endif - if (ibufsize == com->ibufsize) { - mtx_lock_spin(&sio_lock); - return (0); - } - - /* - * Allocate input buffer. The extra factor of 2 in the size is - * to allow for an error byte for each input byte. - */ - ibuf = malloc(2 * ibufsize, M_DEVBUF, M_NOWAIT); - if (ibuf == NULL) { - mtx_lock_spin(&sio_lock); - return (ENOMEM); - } - - /* Initialize non-critical variables. */ - com->ibufold = com->ibuf; - com->ibufsize = ibufsize; - tp = com->tp; - if (tp != NULL) { - tp->t_ififosize = 2 * ibufsize; - tp->t_ispeedwat = (speed_t)-1; - tp->t_ospeedwat = (speed_t)-1; - } - - /* - * Read current input buffer, if any. Continue with interrupts - * disabled. - */ - mtx_lock_spin(&sio_lock); - if (com->iptr != com->ibuf) - sioinput(com); - - /*- - * Initialize critical variables, including input buffer watermarks. - * The external device is asked to stop sending when the buffer - * exactly reaches high water, or when the high level requests it. - * The high level is notified immediately (rather than at a later - * clock tick) when this watermark is reached. - * The buffer size is chosen so the watermark should almost never - * be reached. - * The low watermark is invisibly 0 since the buffer is always - * emptied all at once. - */ - com->iptr = com->ibuf = ibuf; - com->ibufend = ibuf + ibufsize; - com->ierroff = ibufsize; - com->ihighwater = ibuf + 3 * ibufsize / 4; - return (0); -} - -static void -comstart(tp) - struct tty *tp; -{ - struct com_s *com; - int s; - - com = tp->t_sc; - if (com == NULL) - return; - s = spltty(); - mtx_lock_spin(&sio_lock); - if (tp->t_state & TS_TTSTOP) - com->state &= ~CS_TTGO; - else - com->state |= CS_TTGO; - if (tp->t_state & TS_TBLOCK) { -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) { - if ((com_tiocm_get(com) & TIOCM_RTS) && - (com->state & CS_RTS_IFLOW)) - com_tiocm_bic(com, TIOCM_RTS); - } else { - if ((com->mcr_image & MCR_RTS) && - (com->state & CS_RTS_IFLOW)) - outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS); - } -#else - if (com->mcr_image & MCR_RTS && com->state & CS_RTS_IFLOW) - outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS); -#endif - } else { -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) { - if (!(com_tiocm_get(com) & TIOCM_RTS) && - com->iptr < com->ihighwater && - com->state & CS_RTS_IFLOW) - com_tiocm_bis(com, TIOCM_RTS); - } else { - if (!(com->mcr_image & MCR_RTS) && - com->iptr < com->ihighwater && - com->state & CS_RTS_IFLOW) - outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); - } -#else - if (!(com->mcr_image & MCR_RTS) && com->iptr < com->ihighwater - && com->state & CS_RTS_IFLOW) - outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS); -#endif - } - mtx_unlock_spin(&sio_lock); - if (tp->t_state & (TS_TIMEOUT | TS_TTSTOP)) { - ttwwakeup(tp); - splx(s); - return; - } - if (tp->t_outq.c_cc != 0) { - struct lbq *qp; - struct lbq *next; - - if (!com->obufs[0].l_queued) { - com->obufs[0].l_tail - = com->obuf1 + q_to_b(&tp->t_outq, com->obuf1, -#ifdef PC98 - com->obufsize); -#else - sizeof com->obuf1); -#endif - com->obufs[0].l_next = NULL; - com->obufs[0].l_queued = TRUE; - mtx_lock_spin(&sio_lock); - if (com->state & CS_BUSY) { - qp = com->obufq.l_next; - while ((next = qp->l_next) != NULL) - qp = next; - qp->l_next = &com->obufs[0]; - } else { - com->obufq.l_head = com->obufs[0].l_head; - com->obufq.l_tail = com->obufs[0].l_tail; - com->obufq.l_next = &com->obufs[0]; - com->state |= CS_BUSY; - } - mtx_unlock_spin(&sio_lock); - } - 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, -#ifdef PC98 - com->obufsize); -#else - sizeof com->obuf2); -#endif - com->obufs[1].l_next = NULL; - com->obufs[1].l_queued = TRUE; - mtx_lock_spin(&sio_lock); - if (com->state & CS_BUSY) { - qp = com->obufq.l_next; - while ((next = qp->l_next) != NULL) - qp = next; - qp->l_next = &com->obufs[1]; - } else { - com->obufq.l_head = com->obufs[1].l_head; - com->obufq.l_tail = com->obufs[1].l_tail; - com->obufq.l_next = &com->obufs[1]; - com->state |= CS_BUSY; - } - mtx_unlock_spin(&sio_lock); - } - tp->t_state |= TS_BUSY; - } - mtx_lock_spin(&sio_lock); - if (com->state >= (CS_BUSY | CS_TTGO)) - siointr1(com); /* fake interrupt to start output */ - mtx_unlock_spin(&sio_lock); - ttwwakeup(tp); - splx(s); -} - -static void -comstop(tp, rw) - struct tty *tp; - int rw; -{ - struct com_s *com; -#ifdef PC98 - int rsa98_tmp = 0; -#endif - - com = tp->t_sc; - if (com == NULL || com->gone) - return; - mtx_lock_spin(&sio_lock); - if (rw & FWRITE) { -#ifdef PC98 - if (!IS_8251(com->pc98_if_type)) { -#endif - if (com->hasfifo) -#ifdef COM_ESP - /* XXX avoid h/w bug. */ - if (!com->esp) -#endif - sio_setreg(com, com_fifo, - FIFO_XMT_RST | com->fifo_image); -#ifdef PC98 - if (com->pc98_if_type == COM_IF_RSA98III) - for (rsa98_tmp = 0; rsa98_tmp < 2048; rsa98_tmp++) - sio_setreg(com, 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) - com_events -= LOTS_OF_EVENTS; - com->state &= ~(CS_ODONE | CS_BUSY); - com->tp->t_state &= ~TS_BUSY; - } - if (rw & FREAD) { -#ifdef PC98 - if (!IS_8251(com->pc98_if_type)) { - if (com->pc98_if_type == COM_IF_RSA98III) - for (rsa98_tmp = 0; rsa98_tmp < 2048; rsa98_tmp++) - sio_getreg(com, com_data); -#endif - if (com->hasfifo) -#ifdef COM_ESP - /* XXX avoid h/w bug. */ - if (!com->esp) -#endif - sio_setreg(com, com_fifo, - FIFO_RCV_RST | com->fifo_image); -#ifdef PC98 - } -#endif - com_events -= (com->iptr - com->ibuf); - com->iptr = com->ibuf; - } - mtx_unlock_spin(&sio_lock); - comstart(tp); -} - -static int -commodem(struct tty *tp, int sigon, int sigoff) -{ - struct com_s *com; - int bitand, bitor, msr; -#ifdef PC98 - int clr, set; -#endif - - com = tp->t_sc; - if (com->gone) - return(0); - if (sigon != 0 || sigoff != 0) { -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) { - bitand = bitor = 0; - clr = set = 0; - if (sigoff & SER_DTR) { - bitand |= TIOCM_DTR; - clr |= CMD8251_DTR; - } - if (sigoff & SER_RTS) { - bitand |= TIOCM_RTS; - clr |= CMD8251_RxEN | CMD8251_RTS; - } - if (sigon & SER_DTR) { - bitor |= TIOCM_DTR; - set |= CMD8251_TxEN | CMD8251_RxEN | - CMD8251_DTR; - } - if (sigon & SER_RTS) { - bitor |= TIOCM_RTS; - set |= CMD8251_TxEN | CMD8251_RxEN | - CMD8251_RTS; - } - bitand = ~bitand; - mtx_lock_spin(&sio_lock); - com->pc98_prev_modem_status &= bitand; - com->pc98_prev_modem_status |= bitor; - pc98_i8251_clear_or_cmd(com, clr, set); - mtx_unlock_spin(&sio_lock); - return (0); - } else { -#endif - bitand = bitor = 0; - if (sigoff & SER_DTR) - bitand |= MCR_DTR; - if (sigoff & SER_RTS) - bitand |= MCR_RTS; - if (sigon & SER_DTR) - bitor |= MCR_DTR; - if (sigon & SER_RTS) - bitor |= MCR_RTS; - bitand = ~bitand; - mtx_lock_spin(&sio_lock); - com->mcr_image &= bitand; - com->mcr_image |= bitor; - outb(com->modem_ctl_port, com->mcr_image); - mtx_unlock_spin(&sio_lock); - return (0); -#ifdef PC98 - } -#endif - } else { -#ifdef PC98 - if (IS_8251(com->pc98_if_type)) - return (com_tiocm_get(com)); - else { -#endif - bitor = 0; - if (com->mcr_image & MCR_DTR) - bitor |= SER_DTR; - if (com->mcr_image & MCR_RTS) - bitor |= SER_RTS; - msr = com->prev_modem_status; - if (msr & MSR_CTS) - bitor |= SER_CTS; - if (msr & MSR_DCD) - bitor |= SER_DCD; - if (msr & MSR_DSR) - bitor |= SER_DSR; - if (msr & MSR_DSR) - bitor |= SER_DSR; - if (msr & (MSR_RI | MSR_TERI)) - bitor |= SER_RI; - return (bitor); -#ifdef PC98 - } -#endif - } -} - -static void -siosettimeout() -{ - struct com_s *com; - bool_t someopen; - int unit; - - /* - * Set our timeout period to 1 second if no polled devices are open. - * Otherwise set it to max(1/200, 1/hz). - * Enable timeouts iff some device is open. - */ - untimeout(comwakeup, (void *)NULL, sio_timeout_handle); - sio_timeout = hz; - someopen = FALSE; - for (unit = 0; unit < sio_numunits; ++unit) { - com = com_addr(unit); - if (com != NULL && com->tp != NULL - && com->tp->t_state & TS_ISOPEN && !com->gone) { - someopen = TRUE; - if (com->poll || com->poll_output) { - sio_timeout = hz > 200 ? hz / 200 : 1; - break; - } - } - } - if (someopen) { - sio_timeouts_until_log = hz / sio_timeout; - sio_timeout_handle = timeout(comwakeup, (void *)NULL, - sio_timeout); - } else { - /* Flush error messages, if any. */ - sio_timeouts_until_log = 1; - comwakeup((void *)NULL); - untimeout(comwakeup, (void *)NULL, sio_timeout_handle); - } -} - -static void -comwakeup(chan) - void *chan; -{ - struct com_s *com; - int unit; - - sio_timeout_handle = timeout(comwakeup, (void *)NULL, sio_timeout); - - /* - * Recover from lost output interrupts. - * Poll any lines that don't use interrupts. - */ - for (unit = 0; unit < sio_numunits; ++unit) { - com = com_addr(unit); - if (com != NULL && !com->gone - && (com->state >= (CS_BUSY | CS_TTGO) || com->poll)) { - mtx_lock_spin(&sio_lock); - siointr1(com); - mtx_unlock_spin(&sio_lock); - } - } - - /* - * Check for and log errors, but not too often. - */ - if (--sio_timeouts_until_log > 0) - return; - sio_timeouts_until_log = hz / sio_timeout; - for (unit = 0; unit < sio_numunits; ++unit) { - int errnum; - - com = com_addr(unit); - if (com == NULL) - continue; - if (com->gone) - continue; - for (errnum = 0; errnum < CE_NTYPES; ++errnum) { - u_int delta; - u_long total; - - mtx_lock_spin(&sio_lock); - delta = com->delta_error_counts[errnum]; - com->delta_error_counts[errnum] = 0; - mtx_unlock_spin(&sio_lock); - if (delta == 0) - continue; - total = com->error_counts[errnum] += delta; - log(LOG_ERR, "sio%d: %u more %s%s (total %lu)\n", - unit, delta, error_desc[errnum], - delta == 1 ? "" : "s", total); - } - } -} - -#ifdef PC98 -/* commint is called when modem control line changes */ -static void -commint(struct cdev *dev) -{ - register struct tty *tp; - int stat,delta; - struct com_s *com; - - com = dev->si_drv1; - tp = com->tp; - - stat = com_tiocm_get(com); - delta = com_tiocm_get_delta(com); - - if (com->state & CS_CTS_OFLOW) { - if (stat & TIOCM_CTS) - com->state |= CS_ODEVREADY; - else - com->state &= ~CS_ODEVREADY; - } - if ((delta & TIOCM_CAR) && (ISCALLOUT(dev)) == 0) { - if (stat & TIOCM_CAR ) - (void)ttyld_modem(tp, 1); - else if (ttyld_modem(tp, 0) == 0) { - /* negate DTR, RTS */ - com_tiocm_bic(com, (tp->t_cflag & HUPCL) ? - TIOCM_DTR|TIOCM_RTS|TIOCM_LE : TIOCM_LE ); - /* disable IENABLE */ - com_int_TxRx_disable( com ); - } - } -} -#endif - -/* - * Following are all routines needed for SIO to act as console - */ -struct siocnstate { - u_char dlbl; - u_char dlbh; - u_char ier; - u_char cfcr; - u_char mcr; -}; - -/* - * This is a function in order to not replicate "ttyd%d" more - * places than absolutely necessary. - */ -static void -siocnset(struct consdev *cd, int unit) -{ - - cd->cn_unit = unit; - sprintf(cd->cn_name, "ttyd%d", unit); -} - -static speed_t siocngetspeed(Port_t, u_long rclk); -static void siocnclose(struct siocnstate *sp, Port_t iobase); -static void siocnopen(struct siocnstate *sp, Port_t iobase, int speed); -static void siocntxwait(Port_t iobase); - -static cn_probe_t sio_cnprobe; -static cn_init_t sio_cninit; -static cn_term_t sio_cnterm; -static cn_getc_t sio_cngetc; -static cn_putc_t sio_cnputc; -static cn_grab_t sio_cngrab; -static cn_ungrab_t sio_cnungrab; - -CONSOLE_DRIVER(sio); - -static void -siocntxwait(iobase) - Port_t iobase; -{ - int timo; - - /* - * Wait for any pending transmission to finish. Required to avoid - * the UART lockup bug when the speed is changed, and for normal - * transmits. - */ - timo = 100000; - while ((inb(iobase + com_lsr) & (LSR_TSRE | LSR_TXRDY)) - != (LSR_TSRE | LSR_TXRDY) && --timo != 0) - ; -} - -/* - * Read the serial port specified and try to figure out what speed - * it's currently running at. We're assuming the serial port has - * been initialized and is basicly idle. This routine is only intended - * to be run at system startup. - * - * If the value read from the serial port doesn't make sense, return 0. - */ - -static speed_t -siocngetspeed(iobase, rclk) - Port_t iobase; - u_long rclk; -{ - u_int divisor; - u_char dlbh; - u_char dlbl; - u_char cfcr; - - cfcr = inb(iobase + com_cfcr); - outb(iobase + com_cfcr, CFCR_DLAB | cfcr); - - dlbl = inb(iobase + com_dlbl); - dlbh = inb(iobase + com_dlbh); - - outb(iobase + com_cfcr, cfcr); - - divisor = dlbh << 8 | dlbl; - - /* XXX there should be more sanity checking. */ - if (divisor == 0) - return (CONSPEED); - return (rclk / (16UL * divisor)); -} - -static void -siocnopen(sp, iobase, speed) - struct siocnstate *sp; - Port_t iobase; - int speed; -{ - u_int divisor; - u_char dlbh; - u_char dlbl; - - /* - * Save all the device control registers except the fifo register - * and set our default ones (cs8 -parenb speed=comdefaultrate). - * We can't save the fifo register since it is read-only. - */ - sp->ier = inb(iobase + com_ier); - outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */ - siocntxwait(iobase); - sp->cfcr = inb(iobase + com_cfcr); - outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS); - sp->dlbl = inb(iobase + com_dlbl); - sp->dlbh = inb(iobase + com_dlbh); - /* - * Only set the divisor registers if they would change, since on - * some 16550 incompatibles (Startech), setting them clears the - * data input register. This also reduces the effects of the - * UMC8669F bug. - */ - divisor = siodivisor(comdefaultrclk, speed); - dlbl = divisor & 0xFF; - if (sp->dlbl != dlbl) - outb(iobase + com_dlbl, dlbl); - dlbh = divisor >> 8; - if (sp->dlbh != dlbh) - outb(iobase + com_dlbh, dlbh); - outb(iobase + com_cfcr, CFCR_8BITS); - sp->mcr = inb(iobase + com_mcr); - /* - * We don't want interrupts, but must be careful not to "disable" - * them by clearing the MCR_IENABLE bit, since that might cause - * an interrupt by floating the IRQ line. - */ - outb(iobase + com_mcr, (sp->mcr & MCR_IENABLE) | MCR_DTR | MCR_RTS); -} - -static void -siocnclose(sp, iobase) - struct siocnstate *sp; - Port_t iobase; -{ - /* - * Restore the device control registers. - */ - siocntxwait(iobase); - outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS); - if (sp->dlbl != inb(iobase + com_dlbl)) - outb(iobase + com_dlbl, sp->dlbl); - if (sp->dlbh != inb(iobase + com_dlbh)) - outb(iobase + com_dlbh, sp->dlbh); - outb(iobase + com_cfcr, sp->cfcr); - /* - * XXX damp oscillations of MCR_DTR and MCR_RTS by not restoring them. - */ - outb(iobase + com_mcr, sp->mcr | MCR_DTR | MCR_RTS); - outb(iobase + com_ier, sp->ier); -} - -static void -sio_cnprobe(cp) - struct consdev *cp; -{ - speed_t boot_speed; - u_char cfcr; - u_int divisor; - int s, unit; - struct siocnstate sp; - - /* - * Find our first enabled console, if any. If it is a high-level - * console device, then initialize it and return successfully. - * If it is a low-level console device, then initialize it and - * return unsuccessfully. It must be initialized in both cases - * for early use by console drivers and debuggers. Initializing - * the hardware is not necessary in all cases, since the i/o - * routines initialize it on the fly, but it is necessary if - * input might arrive while the hardware is switched back to an - * uninitialized state. We can't handle multiple console devices - * yet because our low-level routines don't take a device arg. - * We trust the user to set the console flags properly so that we - * don't need to probe. - */ - cp->cn_pri = CN_DEAD; - - for (unit = 0; unit < 16; unit++) { /* XXX need to know how many */ - int flags; - - if (resource_disabled("sio", unit)) - continue; - if (resource_int_value("sio", unit, "flags", &flags)) - continue; - if (COM_CONSOLE(flags) || COM_DEBUGGER(flags)) { - int port; - Port_t iobase; - - if (resource_int_value("sio", unit, "port", &port)) - continue; - iobase = port; - s = spltty(); - if ((boothowto & RB_SERIAL) && COM_CONSOLE(flags)) { - boot_speed = - siocngetspeed(iobase, comdefaultrclk); - if (boot_speed) - comdefaultrate = boot_speed; - } - - /* - * Initialize the divisor latch. We can't rely on - * siocnopen() to do this the first time, since it - * avoids writing to the latch if the latch appears - * to have the correct value. Also, if we didn't - * just read the speed from the hardware, then we - * need to set the speed in hardware so that - * switching it later is null. - */ - cfcr = inb(iobase + com_cfcr); - outb(iobase + com_cfcr, CFCR_DLAB | cfcr); - divisor = siodivisor(comdefaultrclk, comdefaultrate); - outb(iobase + com_dlbl, divisor & 0xff); - outb(iobase + com_dlbh, divisor >> 8); - outb(iobase + com_cfcr, cfcr); - - siocnopen(&sp, iobase, comdefaultrate); - - splx(s); - if (COM_CONSOLE(flags) && !COM_LLCONSOLE(flags)) { - siocnset(cp, unit); - cp->cn_pri = COM_FORCECONSOLE(flags) - || boothowto & RB_SERIAL - ? CN_REMOTE : CN_NORMAL; - siocniobase = iobase; - siocnunit = unit; - } -#ifdef GDB - if (COM_DEBUGGER(flags)) - siogdbiobase = iobase; -#endif - } - } -} - -static void -sio_cninit(cp) - struct consdev *cp; -{ - comconsole = cp->cn_unit; -} - -static void -sio_cnterm(cp) - struct consdev *cp; -{ - comconsole = -1; -} - -static void -sio_cngrab(struct consdev *cp) -{ -} - -static void -sio_cnungrab(struct consdev *cp) -{ -} - -static int -sio_cngetc(struct consdev *cd) -{ - int c; - Port_t iobase; - int s; - struct siocnstate sp; - speed_t speed; - - if (cd != NULL && cd->cn_unit == siocnunit) { - iobase = siocniobase; - speed = comdefaultrate; - } else { -#ifdef GDB - iobase = siogdbiobase; - speed = gdbdefaultrate; -#else - return (-1); -#endif - } - s = spltty(); - siocnopen(&sp, iobase, speed); - if (inb(iobase + com_lsr) & LSR_RXRDY) - c = inb(iobase + com_data); - else - c = -1; - siocnclose(&sp, iobase); - splx(s); - return (c); -} - -static void -sio_cnputc(struct consdev *cd, int c) -{ - int need_unlock; - int s; - struct siocnstate sp; - Port_t iobase; - speed_t speed; - - if (cd != NULL && cd->cn_unit == siocnunit) { - iobase = siocniobase; - speed = comdefaultrate; - } else { -#ifdef GDB - iobase = siogdbiobase; - speed = gdbdefaultrate; -#else - return; -#endif - } - s = spltty(); - need_unlock = 0; - if (!kdb_active && sio_inited == 2 && !mtx_owned(&sio_lock)) { - mtx_lock_spin(&sio_lock); - need_unlock = 1; - } - siocnopen(&sp, iobase, speed); - siocntxwait(iobase); - outb(iobase + com_data, c); - siocnclose(&sp, iobase); - if (need_unlock) - mtx_unlock_spin(&sio_lock); - splx(s); -} - -/* - * Remote gdb(1) support. - */ - -#if defined(GDB) - -#include <gdb/gdb.h> - -static gdb_probe_f siogdbprobe; -static gdb_init_f siogdbinit; -static gdb_term_f siogdbterm; -static gdb_getc_f siogdbgetc; -static gdb_putc_f siogdbputc; - -GDB_DBGPORT(sio, siogdbprobe, siogdbinit, siogdbterm, siogdbgetc, siogdbputc); - -static int -siogdbprobe(void) -{ - return ((siogdbiobase != 0) ? 0 : -1); -} - -static void -siogdbinit(void) -{ -} - -static void -siogdbterm(void) -{ -} - -static void -siogdbputc(int c) -{ - sio_cnputc(NULL, c); -} - -static int -siogdbgetc(void) -{ - return (sio_cngetc(NULL)); -} - -#endif - -#ifdef PC98 -/* - * pc98 local function - */ -static void -com_tiocm_bis(struct com_s *com, int msr) -{ - int s; - int tmp = 0; - - s=spltty(); - com->pc98_prev_modem_status |= ( msr & (TIOCM_LE|TIOCM_DTR|TIOCM_RTS) ); - tmp |= CMD8251_TxEN|CMD8251_RxEN; - if ( msr & TIOCM_DTR ) tmp |= CMD8251_DTR; - if ( msr & TIOCM_RTS ) tmp |= CMD8251_RTS; - - pc98_i8251_or_cmd( com, tmp ); - splx(s); -} - -static void -com_tiocm_bic(struct com_s *com, int msr) -{ - int s; - int tmp = msr; - - s=spltty(); - com->pc98_prev_modem_status &= ~( msr & (TIOCM_LE|TIOCM_DTR|TIOCM_RTS) ); - if ( msr & TIOCM_DTR ) tmp |= CMD8251_DTR; - if ( msr & TIOCM_RTS ) tmp |= CMD8251_RTS; - - pc98_i8251_clear_cmd( com, tmp ); - splx(s); -} - -static int -com_tiocm_get(struct com_s *com) -{ - return( com->pc98_prev_modem_status ); -} - -static int -com_tiocm_get_delta(struct com_s *com) -{ - int tmp; - - tmp = com->pc98_modem_delta; - com->pc98_modem_delta = 0; - return( tmp ); -} - -/* convert to TIOCM_?? ( ioctl.h ) */ -static int -pc98_get_modem_status(struct com_s *com) -{ - register int msr; - - msr = com->pc98_prev_modem_status - & ~(TIOCM_CAR|TIOCM_RI|TIOCM_DSR|TIOCM_CTS); - if (com->pc98_8251fifo_enable) { - int stat2; - - stat2 = inb(I8251F_msr); - if ( stat2 & MSR_DCD ) msr |= TIOCM_CAR; - if ( stat2 & MSR_RI ) msr |= TIOCM_RI; - if ( stat2 & MSR_DSR ) msr |= TIOCM_DSR; - if ( stat2 & MSR_CTS ) msr |= TIOCM_CTS; -#if COM_CARRIER_DETECT_EMULATE - if ( msr & (TIOCM_DSR|TIOCM_CTS) ) { - msr |= TIOCM_CAR; - } -#endif - } else { - int stat, stat2; - - stat = inb(com->sts_port); - stat2 = inb(com->in_modem_port); - if ( !(stat2 & CICSCD_CD) ) msr |= TIOCM_CAR; - if ( !(stat2 & CICSCD_CI) ) msr |= TIOCM_RI; - if ( stat & STS8251_DSR ) msr |= TIOCM_DSR; - if ( !(stat2 & CICSCD_CS) ) msr |= TIOCM_CTS; -#if COM_CARRIER_DETECT_EMULATE - if ( msr & (TIOCM_DSR|TIOCM_CTS) ) { - msr |= TIOCM_CAR; - } -#endif - } - return(msr); -} - -static void -pc98_check_msr(void* chan) -{ - int msr, delta; - int s; - register struct tty *tp; - struct com_s *com; - struct cdev *dev; - - dev=(struct cdev *)chan; - com = dev->si_drv1; - tp = dev->si_tty; - - s = spltty(); - msr = pc98_get_modem_status(com); - /* make change flag */ - delta = msr ^ com->pc98_prev_modem_status; - if ( delta & TIOCM_CAR ) { - if ( com->modem_car_chg_timer ) { - if ( -- com->modem_car_chg_timer ) - msr ^= TIOCM_CAR; - } else { - if ((com->modem_car_chg_timer = (msr & TIOCM_CAR) ? - DCD_ON_RECOGNITION : DCD_OFF_TOLERANCE) != 0) - msr ^= TIOCM_CAR; - } - } else - com->modem_car_chg_timer = 0; - delta = ( msr ^ com->pc98_prev_modem_status ) & - (TIOCM_CAR|TIOCM_RI|TIOCM_DSR|TIOCM_CTS); - com->pc98_prev_modem_status = msr; - delta = ( com->pc98_modem_delta |= delta ); - splx(s); - if ( com->modem_checking || (tp->t_state & (TS_ISOPEN)) ) { - if ( delta ) { - commint(dev); - } - timeout(pc98_check_msr, (caddr_t)dev, - PC98_CHECK_MODEM_INTERVAL); - } else { - com->modem_checking = 0; - } -} - -static void -pc98_msrint_start(struct cdev *dev) -{ - struct com_s *com; - int s = spltty(); - - com = dev->si_drv1; - /* modem control line check routine envoke interval is 1/10 sec */ - if ( com->modem_checking == 0 ) { - com->pc98_prev_modem_status = pc98_get_modem_status(com); - com->pc98_modem_delta = 0; - timeout(pc98_check_msr, (caddr_t)dev, - PC98_CHECK_MODEM_INTERVAL); - com->modem_checking = 1; - } - splx(s); -} - -static void -pc98_disable_i8251_interrupt(struct com_s *com, int mod) -{ - /* disable interrupt */ - register int tmp; - - mod |= ~(IEN_Tx|IEN_TxEMP|IEN_Rx); - COM_INT_DISABLE - tmp = inb( com->intr_ctrl_port ) & ~(IEN_Tx|IEN_TxEMP|IEN_Rx); - outb( com->intr_ctrl_port, (com->intr_enable&=~mod) | tmp ); - COM_INT_ENABLE -} - -static void -pc98_enable_i8251_interrupt(struct com_s *com, int mod) -{ - register int tmp; - - COM_INT_DISABLE - tmp = inb( com->intr_ctrl_port ) & ~(IEN_Tx|IEN_TxEMP|IEN_Rx); - outb( com->intr_ctrl_port, (com->intr_enable|=mod) | tmp ); - COM_INT_ENABLE -} - -static int -pc98_check_i8251_interrupt(struct com_s *com) -{ - return ( com->intr_enable & 0x07 ); -} - -static void -pc98_i8251_clear_cmd(struct com_s *com, int x) -{ - int tmp; - - COM_INT_DISABLE - tmp = com->pc98_prev_siocmd & ~(x); - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, 0); - outb(com->cmd_port, tmp); - com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH); - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, FIFO_ENABLE); - COM_INT_ENABLE -} - -static void -pc98_i8251_or_cmd(struct com_s *com, int x) -{ - int tmp; - - COM_INT_DISABLE - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, 0); - tmp = com->pc98_prev_siocmd | (x); - outb(com->cmd_port, tmp); - com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH); - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, FIFO_ENABLE); - COM_INT_ENABLE -} - -static void -pc98_i8251_set_cmd(struct com_s *com, int x) -{ - int tmp; - - COM_INT_DISABLE - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, 0); - tmp = (x); - outb(com->cmd_port, tmp); - com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH); - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, FIFO_ENABLE); - COM_INT_ENABLE -} - -static void -pc98_i8251_clear_or_cmd(struct com_s *com, int clr, int x) -{ - int tmp; - COM_INT_DISABLE - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, 0); - tmp = com->pc98_prev_siocmd & ~(clr); - tmp |= (x); - outb(com->cmd_port, tmp); - com->pc98_prev_siocmd = tmp & ~(CMD8251_ER|CMD8251_RESET|CMD8251_EH); - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, FIFO_ENABLE); - COM_INT_ENABLE -} - -static int -pc98_i8251_get_cmd(struct com_s *com) -{ - return com->pc98_prev_siocmd; -} - -static int -pc98_i8251_get_mod(struct com_s *com) -{ - return com->pc98_prev_siomod; -} - -static void -pc98_i8251_reset(struct com_s *com, int mode, int command) -{ - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, 0); - outb(com->cmd_port, 0); /* dummy */ - DELAY(2); - outb(com->cmd_port, 0); /* dummy */ - DELAY(2); - outb(com->cmd_port, 0); /* dummy */ - DELAY(2); - outb(com->cmd_port, CMD8251_RESET); /* internal reset */ - DELAY(2); - outb(com->cmd_port, mode ); /* mode register */ - com->pc98_prev_siomod = mode; - DELAY(2); - pc98_i8251_set_cmd( com, (command|CMD8251_ER) ); - DELAY(10); - if (com->pc98_8251fifo_enable) - outb(I8251F_fcr, FIFO_ENABLE | FIFO_XMT_RST | FIFO_RCV_RST); -} - -static void -pc98_check_sysclock(void) -{ - /* get system clock from port */ - if ( pc98_machine_type & M_8M ) { - /* 8 MHz system & H98 */ - sysclock = 8; - } else { - /* 5 MHz system */ - sysclock = 5; - } -} - -static void -com_cflag_and_speed_set( struct com_s *com, int cflag, int speed) -{ - int cfcr=0; - int previnterrupt; - int tmp; - u_int count; - - if (pc98_ttspeedtab(com, speed, &count) != 0) - return; - - previnterrupt = pc98_check_i8251_interrupt(com); - pc98_disable_i8251_interrupt( com, IEN_Tx|IEN_TxEMP|IEN_Rx ); - - switch ( cflag&CSIZE ) { - case CS5: - cfcr = MOD8251_5BITS; break; - case CS6: - cfcr = MOD8251_6BITS; break; - case CS7: - cfcr = MOD8251_7BITS; break; - case CS8: - cfcr = MOD8251_8BITS; break; - } - if ( cflag&PARENB ) { - if ( cflag&PARODD ) - cfcr |= MOD8251_PENAB; - else - cfcr |= MOD8251_PENAB | MOD8251_PEVEN; - } - - if ( cflag&CSTOPB ) - cfcr |= MOD8251_STOP2; - else - cfcr |= MOD8251_STOP1; - - if ( count & 0x10000 ) - cfcr |= MOD8251_CLKx1; - else - cfcr |= MOD8251_CLKx16; - - while (!((tmp = inb(com->sts_port)) & STS8251_TxEMP)) - ; - - /* set baud rate from ospeed */ - pc98_set_baud_rate( com, count ); - - if ( cfcr != pc98_i8251_get_mod(com) ) - pc98_i8251_reset(com, cfcr, pc98_i8251_get_cmd(com) ); - - pc98_enable_i8251_interrupt( com, previnterrupt ); -} - -static int -pc98_ttspeedtab(struct com_s *com, int speed, u_int *divisor) -{ - int if_type, 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: - count = ttspeedtab( speed, if_8251_type[if_type].speedtab ); - break; - case COM_IF_B98_01_1: - case COM_IF_B98_01_2: - 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 */ - } -#endif - break; - } - - if (count < 0) - return count; - - *divisor = (u_int) count; - return 0; -} - -static void -pc98_set_baud_rate( struct com_s *com, u_int count ) -{ - int if_type, io, s; - - if_type = com->pc98_if_type & 0x0f; - io = rman_get_start(com->ioportres) & 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); - } - } - - if (count == 0) - return; - - /* set i8253 */ - s = splclock(); - if (count != 3) - 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); -#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); -#endif - break; - } -} -static int -pc98_check_if_type(device_t dev, struct siodev *iod) -{ - int irr, io, if_type, tmp; - static short irq_tab[2][8] = { - { 3, 5, 6, 9, 10, 12, 13, -1}, - { 3, 10, 12, 13, 5, 6, 9, -1} - }; - - if_type = iod->if_type & 0x0f; - iod->irq = 0; - io = isa_get_port(dev) & 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; - - if (pc98_check_8251vfast()) { - PC98SIO_baud_rate_port(if_type) = I8251F_div; - if_8251_type[if_type].speedtab = pc98fast_speedtab; - } - } else { - tmp = inb( iod->mod ) & if_8251_type[if_type].irr_mask; - if ((isa_get_port(dev) & 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(device_get_flags(dev)) || - device_get_unit(dev) == COM_MPMASTER(device_get_flags(dev))) -#endif - if (irr != -1) { - tmp = inb(io | irr); - if (isa_get_port(dev) & 0x01) /* XXX depend on RSB-384 */ - iod->irq = irq_tab[1][tmp >> 3]; - else - iod->irq = irq_tab[0][tmp & 0x07]; - } - iod->cmd = 0; - iod->sts = 0; - iod->mod = 0; - iod->ctrl = 0; - } - if ( iod->irq == -1 ) return -1; - - return 0; -} -static void -pc98_set_ioport(struct com_s *com) -{ - int if_type = com->pc98_if_type & 0x0f; - Port_t io = rman_get_start(com->ioportres) & 0xff00; - - pc98_check_sysclock(); - 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); -} -static int -pc98_check_8251vfast(void) -{ - int i; - - outb(I8251F_div, 0x8c); - DELAY(10); - for (i = 0; i < 100; i++) { - if ((inb(I8251F_div) & 0x80) != 0) { - i = 0; - break; - } - DELAY(1); - } - outb(I8251F_div, 0); - DELAY(10); - for (; i < 100; i++) { - if ((inb(I8251F_div) & 0x80) == 0) - return 1; - DELAY(1); - } - - return 0; -} -static int -pc98_check_8251fifo(void) -{ - u_char tmp1, tmp2; - - tmp1 = inb(I8251F_iir); - DELAY(10); - tmp2 = inb(I8251F_iir); - if (((tmp1 ^ tmp2) & 0x40) != 0 && ((tmp1 | tmp2) & 0x20) == 0) - return 1; - - return 0; -} -#endif /* PC98 defined */ diff --git a/sys/pc98/cbus/sio_cbus.c b/sys/pc98/cbus/sio_cbus.c deleted file mode 100644 index 2df560cd90cd..000000000000 --- a/sys/pc98/cbus/sio_cbus.c +++ /dev/null @@ -1,119 +0,0 @@ -/*- - * Copyright (c) 2001 TAKAHASHI Yoshihiro - * 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. - * - * 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. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/bus.h> -#include <sys/conf.h> -#include <sys/kernel.h> -#include <sys/lock.h> -#include <sys/malloc.h> -#include <sys/mutex.h> -#include <sys/module.h> -#include <sys/tty.h> -#include <machine/bus.h> -#include <sys/timepps.h> - -#include <dev/sio/siovar.h> - -#include <isa/isavar.h> - -static int sio_isa_attach(device_t dev); -static int sio_isa_probe(device_t dev); - -static device_method_t sio_isa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, sio_isa_probe), - DEVMETHOD(device_attach, sio_isa_attach), - DEVMETHOD(device_detach, siodetach), - - { 0, 0 } -}; - -static driver_t sio_isa_driver = { - sio_driver_name, - sio_isa_methods, - 0, -}; - -static struct isa_pnp_id sio_ids[] = { - {0x0100e4a5, "RSA-98III"}, - {0x4180a3b8, NULL}, /* NEC8041 - PC-9821CB-B04 */ - {0x0181a3b8, NULL}, /* NEC8101 - PC-9821CB2-B04 */ - {0x5181a3b8, NULL}, /* NEC8151 - Internal FAX/Modem for Cx3, Cb3 */ - {0x9181a3b8, NULL}, /* NEC8191 - NEC PC-9801-120 */ - {0xe181a3b8, NULL}, /* NEC81E1 - Internal FAX/Modem */ - {0x1182a3b8, NULL}, /* NEC8211 - PC-9801-123 */ - {0x3182a3b8, NULL}, /* NEC8231 - Internal FAX/Modem(Voice) */ - {0x4182a3b8, NULL}, /* NEC8241 - NEC PC-9821NR-B05 */ - {0x5182a3b8, NULL}, /* NEC8251 - Internel FAX/Modem */ - {0x7182a3b8, NULL}, /* NEC8271 - NEC PC-9801-125 */ - {0x11802fbf, NULL}, /* OYO8011 - Internal FAX/Modem for ValueStar(Ring) */ - {0} -}; - -static int -sio_isa_probe(dev) - device_t dev; -{ - int logical_id; - - /* Check isapnp ids */ - if (ISA_PNP_PROBE(device_get_parent(dev), dev, sio_ids) == ENXIO) - return (ENXIO); - - logical_id = isa_get_logicalid(dev); - switch (logical_id) { - case 0x0100e4a5: /* RSA-98III */ - SET_FLAG(dev, SET_IFTYPE(COM_IF_RSA98III)); - break; - case 0x4180a3b8: /* PC-9821CB-B04 */ - case 0x0181a3b8: /* PC-9821CB2-B04 */ - case 0x5181a3b8: /* for Cx3, Cb3 internal */ - case 0x9181a3b8: /* PC-9801-120 */ - case 0xe181a3b8: /* Internal FAX/Modem */ - case 0x1182a3b8: /* PC-9801-123 */ - case 0x3182a3b8: /* FAX/Voice/Modem internal */ - case 0x4182a3b8: /* PC-9821NR-B05 */ - case 0x5182a3b8: /* FAX/Modem internal */ - case 0x7182a3b8: /* PC-9801-125 */ - case 0x11802fbf: /* for ValueStar internal */ - SET_FLAG(dev, SET_IFTYPE(COM_IF_NS16550)); - break; - } - - return (sioprobe(dev, 0, 0UL, 0)); -} - -static int -sio_isa_attach(dev) - device_t dev; -{ - return (sioattach(dev, 0, 0UL)); -} - -DRIVER_MODULE(sio, isa, sio_isa_driver, sio_devclass, 0, 0); diff --git a/sys/pc98/cbus/syscons_cbus.c b/sys/pc98/cbus/syscons_cbus.c deleted file mode 100644 index e5c29795ee2a..000000000000 --- a/sys/pc98/cbus/syscons_cbus.c +++ /dev/null @@ -1,202 +0,0 @@ -/*- - * Copyright (c) 1999 FreeBSD(98) Porting 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include "opt_syscons.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/cons.h> -#include <sys/consio.h> -#include <sys/sysctl.h> - -#include <machine/clock.h> - -#include <pc98/pc98/pc98_machdep.h> - -#include <dev/syscons/syscons.h> - -#include <isa/isavar.h> - -static devclass_t sc_devclass; - -static sc_softc_t main_softc; - -static void -scidentify(driver_t *driver, device_t parent) -{ - - BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "sc", 0); -} - -static int -scprobe(device_t dev) -{ - - /* No pnp support */ - if (isa_get_vendorid(dev)) - return (ENXIO); - - device_set_desc(dev, "System console"); - return (sc_probe_unit(device_get_unit(dev), device_get_flags(dev))); -} - -static int -scattach(device_t dev) -{ - - return sc_attach_unit(device_get_unit(dev), device_get_flags(dev)); -} - -int -sc_max_unit(void) -{ - - return (devclass_get_maxunit(sc_devclass)); -} - -sc_softc_t -*sc_get_softc(int unit, int flags) -{ - sc_softc_t *sc; - - if (unit < 0) - return (NULL); - if ((flags & SC_KERNEL_CONSOLE) != 0) { - /* FIXME: clear if it is wired to another unit! */ - sc = &main_softc; - } else { - sc = device_get_softc(devclass_get_device(sc_devclass, unit)); - if (sc == NULL) - return (NULL); - } - sc->unit = unit; - if ((sc->flags & SC_INIT_DONE) == 0) { - sc->keyboard = -1; - sc->adapter = -1; - sc->mouse_char = SC_MOUSE_CHAR; - } - return (sc); -} - -sc_softc_t -*sc_find_softc(struct video_adapter *adp, struct keyboard *kbd) -{ - sc_softc_t *sc; - int i; - int units; - - sc = &main_softc; - if ((adp == NULL || adp == sc->adp) && - (kbd == NULL || kbd == sc->kbd)) - return (sc); - units = devclass_get_maxunit(sc_devclass); - for (i = 0; i < units; ++i) { - sc = device_get_softc(devclass_get_device(sc_devclass, i)); - if (sc == NULL) - continue; - if ((adp == NULL || adp == sc->adp) && - (kbd == NULL || kbd == sc->kbd)) - return (sc); - } - return (NULL); -} - -int -sc_get_cons_priority(int *unit, int *flags) -{ - const char *at; - int f, u; - - *unit = -1; - for (u = 0; u < 16; u++) { - if (resource_disabled(SC_DRIVER_NAME, u)) - continue; - if (resource_string_value(SC_DRIVER_NAME, u, "at", &at) != 0) - continue; - if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0) - f = 0; - if (f & SC_KERNEL_CONSOLE) { - /* the user designates this unit to be the console */ - *unit = u; - *flags = f; - break; - } - if (*unit < 0) { - /* ...otherwise remember the first found unit */ - *unit = u; - *flags = f; - } - } - if (*unit < 0) { - *unit = 0; - *flags = 0; - } - return (CN_INTERNAL); -} - -void -sc_get_bios_values(bios_values_t *values) -{ - values->cursor_start = 15; - values->cursor_end = 16; - values->shift_state = 0; - values->bell_pitch = BELL_PITCH; -} - -int -sc_tone(int herz) -{ - - if (herz) { - if (timer_spkr_acquire()) - return (EBUSY); - timer_spkr_setfreq(herz); - } else - timer_spkr_release(); - - return (0); -} - -static device_method_t sc_methods[] = { - DEVMETHOD(device_identify, scidentify), - DEVMETHOD(device_probe, scprobe), - DEVMETHOD(device_attach, scattach), - { 0, 0 } -}; - -static driver_t sc_driver = { - SC_DRIVER_NAME, - sc_methods, - sizeof(sc_softc_t), -}; - -DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0); |