summaryrefslogtreecommitdiffstats
path: root/sys/pc98
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1999-04-18 14:42:20 +0000
committerkato <kato@FreeBSD.org>1999-04-18 14:42:20 +0000
commit6b69df13a813066197b2439adba31c602f84361b (patch)
treebbea6f8600634a59bff89d96d4e7ac1343174aa3 /sys/pc98
parentda8f615ce6e7fe473ad98685260ce5fb84a39e75 (diff)
downloadFreeBSD-src-6b69df13a813066197b2439adba31c602f84361b.zip
FreeBSD-src-6b69df13a813066197b2439adba31c602f84361b.tar.gz
Sync with follwing files:
Path Revision i386/conf/GENERIC 1.162 i386/conf/Makefile.i386 1.146 i386/conf/files.i386 1.236 i386/conf/options.i386 1.111 i386/i386/machdep.c 1.329 i386/i386/userconfig.c 1.134 i386/isa/fd.c 1.135 i386/isa/if_ed.c 1.151 i386/isa/isa_dam.c 1.1 i386/isa/npx.c 1.67 isa/sio.c 1.224 dev/syscons/syscons.c 1.300 i386/isa/wd.c 1.194 isa/vga_isa.c 1.5 isa/atkbd_isa.c 1.3 isa/syscons_isa.c 1.2 Submitted by: Takahashi Yoshihiro <nyan@wyvern.cc.kogakuin.ac.jp>
Diffstat (limited to 'sys/pc98')
-rw-r--r--sys/pc98/cbus/cbus_dma.c560
-rw-r--r--sys/pc98/cbus/fdc.c1365
-rw-r--r--sys/pc98/cbus/gdc.c76
-rw-r--r--sys/pc98/cbus/pckbd.c85
-rw-r--r--sys/pc98/cbus/sio.c587
-rw-r--r--sys/pc98/conf/GENERIC64
-rw-r--r--sys/pc98/conf/GENERIC9864
-rw-r--r--sys/pc98/conf/Makefile.pc9860
-rw-r--r--sys/pc98/conf/files.pc9841
-rw-r--r--sys/pc98/conf/options.pc989
-rw-r--r--sys/pc98/i386/machdep.c27
-rw-r--r--sys/pc98/i386/userconfig.c129
-rw-r--r--sys/pc98/pc98/fd.c1365
-rw-r--r--sys/pc98/pc98/if_ed.c7
-rw-r--r--sys/pc98/pc98/isa_dma.c560
-rw-r--r--sys/pc98/pc98/machdep.c27
-rw-r--r--sys/pc98/pc98/npx.c179
-rw-r--r--sys/pc98/pc98/pc98gdc.c76
-rw-r--r--sys/pc98/pc98/pc98kbd.c85
-rw-r--r--sys/pc98/pc98/sio.c587
-rw-r--r--sys/pc98/pc98/syscons.c58
-rw-r--r--sys/pc98/pc98/wd.c33
22 files changed, 3918 insertions, 2126 deletions
diff --git a/sys/pc98/cbus/cbus_dma.c b/sys/pc98/cbus/cbus_dma.c
new file mode 100644
index 0000000..6599b05
--- /dev/null
+++ b/sys/pc98/cbus/cbus_dma.c
@@ -0,0 +1,560 @@
+/*-
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)isa.c 7.2 (Berkeley) 5/13/91
+ * $Id: isa_dma.c,v 1.1 1999/04/16 21:22:24 peter Exp $
+ */
+
+/*
+ * 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()
+ */
+
+#ifdef PC98
+#include "opt_pc98.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <machine/ipl.h>
+#include <machine/md_var.h>
+#ifdef APIC_IO
+#include <machine/smp.h>
+#endif /* APIC_IO */
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <i386/isa/isa_device.h>
+#include <i386/isa/intr_machdep.h>
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
+#include <i386/isa/isa.h>
+#endif
+#include <i386/isa/ic/i8237.h>
+
+#include <sys/interrupt.h>
+
+#include "pnp.h"
+#if NPNP > 0
+#include <i386/isa/pnp.h>
+#endif
+
+/*
+** Register definitions for DMA controller 1 (channels 0..3):
+*/
+#ifdef PC98
+#define DMA1_CHN(c) (IO_DMA + (4*(c))) /* addr reg for channel c */
+#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 */
+#else
+#define DMA1_CHN(c) (IO_DMA1 + 1*(2*(c))) /* addr reg for channel c */
+#define DMA1_SMSK (IO_DMA1 + 1*10) /* single mask register */
+#define DMA1_MODE (IO_DMA1 + 1*11) /* mode register */
+#define DMA1_FFC (IO_DMA1 + 1*12) /* clear first/last FF */
+#endif
+
+/*
+** Register definitions for DMA controller 2 (channels 4..7):
+*/
+#define DMA2_CHN(c) (IO_DMA2 + 2*(2*(c))) /* addr reg for channel c */
+#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */
+#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */
+#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */
+
+static int isa_dmarangecheck __P((caddr_t va, u_int length, int chan));
+
+#ifdef PC98
+static caddr_t dma_bouncebuf[4];
+static u_int dma_bouncebufsize[4];
+#else
+static caddr_t dma_bouncebuf[8];
+static u_int dma_bouncebufsize[8];
+#endif
+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;
+
+#ifdef PC98
+#define VALID_DMA_MASK (3)
+#else
+#define VALID_DMA_MASK (7)
+#endif
+
+/* high byte of address is stored in this port for i-th dma channel */
+#ifdef PC98
+static int dmapageport[8] = { 0x27, 0x21, 0x23, 0x25 };
+#else
+static int dmapageport[8] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
+#endif
+
+/*
+ * Setup a DMA channel's bounce buffer.
+ */
+void
+isa_dmainit(chan, bouncebufsize)
+ int chan;
+ u_int bouncebufsize;
+{
+ void *buf;
+
+#ifdef DIAGNOSTIC
+ if (chan & ~VALID_DMA_MASK)
+ panic("isa_dmainit: channel out of range");
+
+ if (dma_bouncebuf[chan] != NULL)
+ panic("isa_dmainit: impossible request");
+#endif
+
+ dma_bouncebufsize[chan] = bouncebufsize;
+
+ /* Try malloc() first. It works better if it works. */
+ buf = malloc(bouncebufsize, M_DEVBUF, M_NOWAIT);
+ if (buf != NULL) {
+ if (isa_dmarangecheck(buf, bouncebufsize, chan) == 0) {
+ dma_bouncebuf[chan] = buf;
+ return;
+ }
+ free(buf, M_DEVBUF);
+ }
+ buf = contigmalloc(bouncebufsize, M_DEVBUF, M_NOWAIT, 0ul, 0xfffffful,
+ 1ul, chan & 4 ? 0x20000ul : 0x10000ul);
+ if (buf == NULL)
+ printf("isa_dmainit(%d, %d) failed\n", chan, bouncebufsize);
+ else
+ dma_bouncebuf[chan] = buf;
+}
+
+/*
+ * 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
+
+ if (dma_inuse & (1 << chan)) {
+ printf("isa_dma_acquire: channel %d already in use\n", chan);
+ return (EBUSY);
+ }
+ dma_inuse |= (1 << chan);
+ dma_auto_mode &= ~(1 << chan);
+
+ 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");
+
+ if ((dma_inuse & (1 << chan)) == 0)
+ printf("isa_dma_release: channel %d not in use\n", chan);
+#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);
+}
+
+#ifndef PC98
+/*
+ * isa_dmacascade(): program 8237 DMA controller channel to accept
+ * external dma control by a board.
+ */
+void
+isa_dmacascade(chan)
+ int chan;
+{
+#ifdef DIAGNOSTIC
+ if (chan & ~VALID_DMA_MASK)
+ panic("isa_dmacascade: channel out of range");
+#endif
+
+ /* set dma channel mode, and set dma channel mode */
+ if ((chan & 4) == 0) {
+ outb(DMA1_MODE, DMA37MD_CASCADE | chan);
+ outb(DMA1_SMSK, chan);
+ } else {
+ outb(DMA2_MODE, DMA37MD_CASCADE | (chan & 3));
+ outb(DMA2_SMSK, chan & 3);
+ }
+}
+#endif
+
+/*
+ * 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_offset_t phys;
+ int waport;
+ caddr_t newaddr;
+
+#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");
+
+ if ((dma_inuse & (1 << chan)) == 0)
+ printf("isa_dmastart: channel %d not acquired\n", chan);
+#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 (isa_dmarangecheck(addr, nbytes, chan)) {
+ 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 & B_READ))
+ bcopy(addr, newaddr, nbytes);
+ addr = newaddr;
+ }
+
+ /* translate to physical */
+ phys = pmap_extract(pmap_kernel(), (vm_offset_t)addr);
+
+ if (flags & B_RAW) {
+ dma_auto_mode |= (1 << chan);
+ } else {
+ dma_auto_mode &= ~(1 << chan);
+ }
+
+#ifndef PC98
+ if ((chan & 4) == 0) {
+ /*
+ * Program one of DMA channels 0..3. These are
+ * byte mode channels.
+ */
+#endif
+ /* set dma channel mode, and reset address ff */
+
+ /* If B_RAW flag is set, then use autoinitialise mode */
+ if (flags & B_RAW) {
+ if (flags & B_READ)
+ outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_WRITE|chan);
+ else
+ outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_READ|chan);
+ }
+ else
+ if (flags & B_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 + 1, --nbytes);
+ outb(waport + 1, nbytes>>8);
+
+ /* unmask channel */
+ outb(DMA1_SMSK, chan);
+#ifndef PC98
+ } else {
+ /*
+ * Program one of DMA channels 4..7. These are
+ * word mode channels.
+ */
+ /* set dma channel mode, and reset address ff */
+
+ /* If B_RAW flag is set, then use autoinitialise mode */
+ if (flags & B_RAW) {
+ if (flags & B_READ)
+ outb(DMA2_MODE, DMA37MD_AUTO|DMA37MD_WRITE|(chan&3));
+ else
+ outb(DMA2_MODE, DMA37MD_AUTO|DMA37MD_READ|(chan&3));
+ }
+ else
+ if (flags & B_READ)
+ outb(DMA2_MODE, DMA37MD_SINGLE|DMA37MD_WRITE|(chan&3));
+ else
+ outb(DMA2_MODE, DMA37MD_SINGLE|DMA37MD_READ|(chan&3));
+ outb(DMA2_FFC, 0);
+
+ /* send start address */
+ waport = DMA2_CHN(chan - 4);
+ outb(waport, phys>>1);
+ outb(waport, phys>>9);
+ outb(dmapageport[chan], phys>>16);
+
+ /* send count */
+ nbytes >>= 1;
+ outb(waport + 2, --nbytes);
+ outb(waport + 2, nbytes>>8);
+
+ /* unmask channel */
+ outb(DMA2_SMSK, chan & 3);
+ }
+#endif
+}
+
+void
+isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
+{
+#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
+
+ if (((dma_busy & (1 << chan)) == 0) &&
+ (dma_auto_mode & (1 << chan)) == 0 )
+ printf("isa_dmadone: channel %d not busy\n", chan);
+
+#ifdef PC98
+ if ((dma_auto_mode & (1 << chan)) == 0)
+ outb(DMA1_SMSK, (chan & 3) | 4);
+#else
+ if ((dma_auto_mode & (1 << chan)) == 0)
+ outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
+#endif
+
+ if (dma_bounced & (1 << chan)) {
+ /* copy bounce buffer on read */
+ if (flags & B_READ)
+ bcopy(dma_bouncebuf[chan], addr, nbytes);
+
+ dma_bounced &= ~(1 << chan);
+ }
+ dma_busy &= ~(1 << chan);
+}
+
+/*
+ * 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_offset_t phys, priorpage = 0, 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(pmap_kernel(), (vm_offset_t)va));
+#ifdef EPSON_BOUNCEDMA
+#define ISARAM_END 0xf00000
+#else
+#define ISARAM_END RAM_END
+#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.
+ *
+ */
+int
+isa_dmastatus(int chan)
+{
+ u_long cnt = 0;
+ int ffport, waport;
+ u_long low1, high1, low2, high2;
+
+ /* 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 ;
+ }
+#ifdef PC98
+ ffport = DMA1_FFC;
+ waport = DMA1_CHN(chan) + 2;
+#else
+ if (chan < 4) { /* low DMA controller */
+ ffport = DMA1_FFC;
+ waport = DMA1_CHN(chan) + 1;
+ } else { /* high DMA controller */
+ ffport = DMA2_FFC;
+ waport = DMA2_CHN(chan - 4) + 2;
+ }
+#endif
+
+ 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);
+}
+
+/*
+ * Stop a DMA transfer currently in progress.
+ */
+int
+isa_dmastop(int chan)
+{
+ 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);
+ return -2 ;
+ }
+
+ if ((chan & 4) == 0) {
+ outb(DMA1_SMSK, (chan & 3) | 4 /* disable mask */);
+ } else {
+#ifndef PC98
+ outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
+#endif
+ }
+ return(isa_dmastatus(chan));
+}
diff --git a/sys/pc98/cbus/fdc.c b/sys/pc98/cbus/fdc.c
index c70dc56..7d6c8bb 100644
--- a/sys/pc98/cbus/fdc.c
+++ b/sys/pc98/cbus/fdc.c
@@ -47,7 +47,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.52 1999/02/10 00:03:58 ken Exp $
+ * $Id: fd.c,v 1.53 1999/04/06 03:12:22 peter Exp $
*
*/
@@ -60,33 +60,44 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <machine/clock.h>
-#include <machine/ioctl_fd.h>
#include <sys/disklabel.h>
-#include <sys/buf.h>
#include <sys/devicestat.h>
+#include <sys/fcntl.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/proc.h>
#include <sys/syslog.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/clock.h>
+#include <machine/ioctl_fd.h>
+#include <machine/resource.h>
+#include <machine/stdarg.h>
+
+#ifdef DEVFS
+#include <sys/devfsext.h>
+#endif /* DEVFS */
+
+#include <isa/isavar.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
#include <pc98/pc98/epsonio.h>
-#include <i386/isa/isa_device.h>
+#include <i386/isa/isa_dma.h>
#include <pc98/pc98/fdreg.h>
#else
#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
+#include <i386/isa/isa_dma.h>
#include <i386/isa/fdreg.h>
-#include <i386/isa/rtc.h>
#endif
#include <i386/isa/fdc.h>
-#include <machine/stdarg.h>
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif /* DEVFS */
+#include <i386/isa/rtc.h>
/* misuse a flag to identify format operation */
#define B_FORMAT B_XXX
@@ -188,13 +199,13 @@ static struct fd_type fd_types[NUMTYPES] =
/***********************************************************************\
* Per controller structure. *
\***********************************************************************/
-struct fdc_data fdc_data[NFDC];
+static devclass_t fdc_devclass;
/***********************************************************************\
* Per drive structure. *
* N per controller (DRVS_PER_CTLR) *
\***********************************************************************/
-static struct fd_data {
+struct fd_data {
struct fdc_data *fdc; /* pointer to controller structure */
int fdsu; /* this units number on this controller */
int type; /* Drive type (FD_1440...) */
@@ -219,7 +230,10 @@ static struct fd_data {
#ifdef PC98
int pc98_trans;
#endif
-} fd_data[NFD];
+ device_t dev;
+ fdu_t fdu;
+};
+static devclass_t fd_devclass;
#ifdef EPSON_NRDISK
typedef unsigned int nrd_t;
@@ -290,29 +304,26 @@ nrd_info(addr)
static int yeattach(struct isa_device *);
#endif
-/* autoconfig functions */
-static int fdprobe(struct isa_device *);
-static int fdattach(struct isa_device *);
-
/* needed for ft driver, thus exported */
-int in_fdc(fdcu_t);
-int out_fdc(fdcu_t, int);
+int in_fdc(struct fdc_data *);
+int out_fdc(struct fdc_data *, int);
/* internal functions */
-static void set_motor(fdcu_t, int, int);
+static void fdc_add_device(device_t, const char *, int);
+static void fdc_intr(void *);
+static void set_motor(struct fdc_data *, int, int);
# define TURNON 1
# define TURNOFF 0
static timeout_t fd_turnoff;
static timeout_t fd_motor_on;
-static void fd_turnon(fdu_t);
+static void fd_turnon(struct fd_data *);
static void fdc_reset(fdc_p);
-static int fd_in(fdcu_t, int *);
-static void fdstart(fdcu_t);
+static int fd_in(struct fdc_data *, int *);
+static void fdstart(struct fdc_data *);
static timeout_t fd_iotimeout;
static timeout_t fd_pseudointr;
-static ointhand2_t fdintr;
-static int fdstate(fdcu_t, fdc_p);
-static int retrier(fdcu_t);
+static int fdstate(struct fdc_data *);
+static int retrier(struct fdc_data *);
static int fdformat(dev_t, struct fd_formb *, struct proc *);
static int enable_fifo(fdc_p fdc);
@@ -451,13 +462,6 @@ static int yeintr(struct pccard_devinfo *devi)
#endif /* NCARD > 0 */
#endif /* FDC_YE */
-
-/* autoconfig structure */
-
-struct isa_driver fdcdriver = {
- fdprobe, fdattach, "fdc",
-};
-
static d_open_t Fdopen; /* NOTE, not fdopen */
static d_read_t fdread;
static d_write_t fdwrite;
@@ -469,28 +473,18 @@ static d_strategy_t fdstrategy;
#define CDEV_MAJOR 9
#define BDEV_MAJOR 2
-
-static struct cdevsw fd_cdevsw = {
- Fdopen, fdclose, fdread, fdwrite,
- fdioctl, nostop, nullreset, nodevtotty,
- seltrue, nommap, fdstrategy, "fd",
- NULL, -1, nodump, nopsize,
- D_DISK, 0, -1 };
-
-
-static struct isa_device *fdcdevs[NFDC];
-
-
static int
-fdc_err(fdcu_t fdcu, const char *s)
+fdc_err(struct fdc_data *fdc, const char *s)
{
- fdc_data[fdcu].fdc_errs++;
- if(s) {
- if(fdc_data[fdcu].fdc_errs < FDC_ERRMAX)
- printf("fdc%d: %s", fdcu, s);
- else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX)
- printf("fdc%d: too many errors, not logging any more\n",
- fdcu);
+ fdc->fdc_errs++;
+ if (s) {
+ if (fdc->fdc_errs < FDC_ERRMAX) {
+ device_print_prettyname(fdc->fdc_dev);
+ printf("%s", s);
+ } else if (fdc->fdc_errs == FDC_ERRMAX) {
+ device_print_prettyname(fdc->fdc_dev);
+ printf("too many errors, not logging any more\n");
+ }
}
return FD_FAILED;
@@ -502,9 +496,8 @@ fdc_err(fdcu_t fdcu, const char *s)
* # of output bytes, output bytes as ints ...,
* # of input bytes, input bytes as ints ...
*/
-
static int
-fd_cmd(fdcu_t fdcu, int n_out, ...)
+fd_cmd(struct fdc_data *fdc, int n_out, ...)
{
u_char cmd;
int n_in;
@@ -517,26 +510,26 @@ fd_cmd(fdcu_t fdcu, int n_out, ...)
va_start(ap, n_out);
for (n = 0; n < n_out; n++)
{
- if (out_fdc(fdcu, va_arg(ap, int)) < 0)
+ if (out_fdc(fdc, va_arg(ap, int)) < 0)
{
char msg[50];
snprintf(msg, sizeof(msg),
"cmd %x failed at out byte %d of %d\n",
cmd, n + 1, n_out);
- return fdc_err(fdcu, msg);
+ return fdc_err(fdc, msg);
}
}
n_in = va_arg(ap, int);
for (n = 0; n < n_in; n++)
{
int *ptr = va_arg(ap, int *);
- if (fd_in(fdcu, ptr) < 0)
+ if (fd_in(fdc, ptr) < 0)
{
char msg[50];
snprintf(msg, sizeof(msg),
"cmd %02x failed at in byte %d of %d\n",
cmd, n + 1, n_in);
- return fdc_err(fdcu, msg);
+ return fdc_err(fdc, msg);
}
}
@@ -557,8 +550,8 @@ enable_fifo(fdc_p fdc)
* first byte, and check for an early turn of data directon.
*/
- if (out_fdc(fdc->fdcu, I8207X_CONFIGURE) < 0)
- return fdc_err(fdc->fdcu, "Enable FIFO failed\n");
+ if (out_fdc(fdc, I8207X_CONFIGURE) < 0)
+ return fdc_err(fdc, "Enable FIFO failed\n");
/* If command is invalid, return */
j = 100000;
@@ -569,17 +562,17 @@ enable_fifo(fdc_p fdc)
return FD_FAILED;
}
if (j<0 ||
- fd_cmd(fdc->fdcu, 3,
+ fd_cmd(fdc, 3,
0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
fdc_reset(fdc);
- return fdc_err(fdc->fdcu, "Enable FIFO failed\n");
+ return fdc_err(fdc, "Enable FIFO failed\n");
}
fdc->flags |= FDC_HAS_FIFO;
return 0;
}
- if (fd_cmd(fdc->fdcu, 4,
+ if (fd_cmd(fdc, 4,
I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0)
- return fdc_err(fdc->fdcu, "Re-enable FIFO failed\n");
+ return fdc_err(fdc, "Re-enable FIFO failed\n");
return 0;
}
@@ -588,9 +581,9 @@ fd_sense_drive_status(fdc_p fdc, int *st3p)
{
int st3;
- if (fd_cmd(fdc->fdcu, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
+ if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
{
- return fdc_err(fdc->fdcu, "Sense Drive Status failed\n");
+ return fdc_err(fdc, "Sense Drive Status failed\n");
}
if (st3p)
*st3p = st3;
@@ -601,7 +594,7 @@ fd_sense_drive_status(fdc_p fdc, int *st3p)
static int
fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
{
- int st0, cyl;
+ int cyl, st0, ret;
#ifdef EPSON_NRDISK
if (fdc->fdu == nrdu) {
@@ -612,11 +605,9 @@ fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
}
else {
#endif /* EPSON_NRDISK */
- int ret = fd_cmd(fdc->fdcu, 1, NE7CMD_SENSEI, 1, &st0);
-
- if (ret)
- {
- (void)fdc_err(fdc->fdcu,
+ ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0);
+ if (ret) {
+ (void)fdc_err(fdc,
"sense intr err reading stat reg 0\n");
return ret;
}
@@ -624,17 +615,15 @@ fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
if (st0p)
*st0p = st0;
- if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV)
- {
+ if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) {
/*
* There doesn't seem to have been an interrupt.
*/
return FD_NOT_VALID;
}
- if (fd_in(fdc->fdcu, &cyl) < 0)
- {
- return fdc_err(fdc->fdcu, "can't get cyl num\n");
+ if (fd_in(fdc, &cyl) < 0) {
+ return fdc_err(fdc, "can't get cyl num\n");
}
if (cylp)
@@ -652,8 +641,7 @@ fd_read_status(fdc_p fdc, int fdsu)
{
int i, ret;
- for (i = 0; i < 7; i++)
- {
+ for (i = 0; i < 7; i++) {
/*
* XXX types are poorly chosen. Only bytes can by read
* from the hardware, but fdc->status[] wants u_ints and
@@ -677,7 +665,7 @@ fd_read_status(fdc_p fdc, int fdsu)
}
else {
#endif /* EPSON_NRDISK */
- ret = fd_in(fdc->fdcu, &status);
+ ret = fd_in(fdc, &status);
fdc->status[i] = status;
if (ret != 0)
break;
@@ -701,26 +689,19 @@ fd_read_status(fdc_p fdc, int fdsu)
static int pc98_trans = 0; /* 0 : HD , 1 : DD , 2 : 1.44 */
static int pc98_trans_prev = 0;
-static void set_density(fdcu_t, fdu_t);
-static int pc98_fd_check_ready(fdu_t);
-
-static void set_density(fdcu, fdu)
- fdcu_t fdcu;
- fdu_t fdu;
+static void set_density(fdc_p fdc)
{
/* always motor on */
- outb(IO_FDPORT,
- (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
+ outb(IO_FDPORT, (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
DELAY(100);
- outb(fdc_data[fdcu].baseport + FDOUT, FDO_RST | FDO_DMAE);
+ outb(fdc->baseport + FDOUT, FDO_RST | FDO_DMAE);
/* in the case of note W, always inhibit 100ms timer */
}
-static int pc98_fd_check_ready(fdu)
- fdu_t fdu;
+static int pc98_fd_check_ready(fdu_t fdu)
{
- fd_p fd = fd_data + fdu;
- fdcu_t fdcu = fd->fdc->fdcu;
+ fd_p fd = devclass_get_softc(fd_devclass, fdu);
+ struct fdc_data *fdc = fd->fdc;
int retry = 0;
#ifdef EPSON_NRDISK
@@ -730,13 +711,13 @@ static int pc98_fd_check_ready(fdu)
}
#endif
while (retry++ < 30000) {
- set_motor(fdcu, fd->fdsu, TURNON);
- out_fdc(fdcu, NE7CMD_SENSED); /* Sense Drive Status */
+ set_motor(fdc, fd->fdsu, TURNON);
+ out_fdc(fdc, NE7CMD_SENSED); /* Sense Drive Status */
DELAY(100);
- out_fdc(fdcu, fdu); /* Drive number */
+ out_fdc(fdc, fdu); /* Drive number */
DELAY(100);
- if ((in_fdc(fdcu) & NE7_ST3_RD)){
- outb(fdc_data[fdcu].baseport + FDOUT,
+ if ((in_fdc(fdc) & NE7_ST3_RD)){
+ outb(fdc->baseport + FDOUT,
FDO_DMAE | FDO_MTON);
DELAY(10);
return 0;
@@ -746,43 +727,104 @@ static int pc98_fd_check_ready(fdu)
}
#endif
-
-/*
- * probe for existance of controller
- */
static int
-fdprobe(struct isa_device *dev)
+fdc_probe(device_t dev)
{
- fdcu_t fdcu = dev->id_unit;
- if(fdc_data[fdcu].flags & FDC_ATTACHED)
- {
- printf("fdc%d: unit used multiple times\n", fdcu);
- return 0;
+ int error, i, ic_type;
+ struct fdc_data *fdc;
+ char myname[8]; /* better be long enough */
+
+ fdc = device_get_softc(dev);
+ bzero(fdc, sizeof *fdc);
+ fdc->fdc_dev = dev;
+ fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0;
+ fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0;
+
+ fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
+ &fdc->rid_ioport, 0ul, ~0ul,
+ IO_FDCSIZE, RF_ACTIVE);
+ if (fdc->res_ioport == 0) {
+ device_print_prettyname(dev);
+ printf("cannot reserve I/O port range\n");
+ error = ENXIO;
+ goto out;
}
-
- fdcdevs[fdcu] = dev;
- fdc_data[fdcu].baseport = dev->id_iobase;
+ fdc->baseport = fdc->res_ioport->r_start;
+
+ fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &fdc->rid_irq, 0ul, ~0ul, 1,
+ RF_ACTIVE);
+ if (fdc->res_irq == 0) {
+ device_print_prettyname(dev);
+ printf("cannot reserve interrupt line\n");
+ error = ENXIO;
+ goto out;
+ }
+ fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ,
+ &fdc->rid_drq, 0ul, ~0ul, 1,
+ RF_ACTIVE);
+ if (fdc->res_drq == 0) {
+ device_print_prettyname(dev);
+ printf("cannot reserve DMA request line\n");
+ error = ENXIO;
+ goto out;
+ }
+ fdc->dmachan = fdc->res_drq->r_start;
+ error = BUS_SETUP_INTR(device_get_parent(dev), dev,
+ fdc->res_irq, fdc_intr, fdc, &fdc->fdc_intr);
#ifndef PC98
/* First - lets reset the floppy controller */
- outb(dev->id_iobase+FDOUT, 0);
+ outb(fdc->baseport + FDOUT, 0);
DELAY(100);
- outb(dev->id_iobase+FDOUT, FDO_FRST);
+ outb(fdc->baseport + FDOUT, FDO_FRST);
#endif
/* see if it can handle a command */
#ifdef PC98
- if (fd_cmd(fdcu,
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
- 0))
+ if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240),
+ NE7_SPEC_2(2, 0), 0)) {
+ error = ENXIO;
+ goto out;
+ }
#else
- if (fd_cmd(fdcu,
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
- 0))
+ if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
+ NE7_SPEC_2(2, 0), 0)) {
+ error = ENXIO;
+ goto out;
+ }
#endif
- {
- return(0);
+
+#ifndef PC98
+ if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) {
+ ic_type = (u_char)ic_type;
+ switch (ic_type) {
+ case 0x80:
+ device_set_desc(dev, "NEC 765 or clone");
+ fdc->fdct = FDC_NE765;
+ break;
+ case 0x81:
+ device_set_desc(dev, "Intel 82077 or clone");
+ fdc->fdct = FDC_I82077;
+ break;
+ case 0x90:
+ device_set_desc(dev, "NEC 72065B or clone");
+ fdc->fdct = FDC_NE72065;
+ break;
+ default:
+ device_set_desc(dev, "generic floppy controller");
+ fdc->fdct = FDC_UNKNOWN;
+ break;
+ }
}
+#endif
+
+ snprintf(myname, sizeof(myname), "%s%d", device_get_name(dev),
+ device_get_unit(dev));
+ for (i = resource_query_string(-1, "at", myname); i != -1;
+ i = resource_query_string(i, "at", myname))
+ fdc_add_device(dev, resource_query_name(i),
+ resource_query_unit(i));
#ifdef FDC_YE
/*
* don't succeed on probe; wait
@@ -791,385 +833,413 @@ fdprobe(struct isa_device *dev)
if (dev->id_flags & FDC_IS_PCMCIA)
return(0);
#endif
- return (IO_FDCSIZE);
+ return (0);
+
+out:
+ if (fdc->fdc_intr)
+ BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
+ fdc->fdc_intr);
+ if (fdc->res_irq != 0) {
+ bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
+ fdc->res_irq);
+ bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
+ fdc->res_irq);
+ }
+ if (fdc->res_ioport != 0) {
+ bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
+ fdc->res_ioport);
+ bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
+ fdc->res_ioport);
+ }
+ if (fdc->res_drq != 0) {
+ bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
+ fdc->res_drq);
+ bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
+ fdc->res_drq);
+ }
+ return (error);
}
/*
- * wire controller into system, look for floppy units
+ * Aped dfr@freebsd.org's isa_add_device().
*/
+static void
+fdc_add_device(device_t dev, const char *name, int unit)
+{
+ int disabled, *ivar;
+ device_t child;
+
+ ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT);
+ if (ivar == 0)
+ return;
+ if (resource_int_value(name, unit, "drive", ivar) == 0)
+ *ivar = 0;
+ child = device_add_child(dev, name, unit, ivar);
+ if (child == 0)
+ return;
+ if (resource_int_value(name, unit, "disabled", &disabled) == 0)
+ device_disable(child);
+}
+
static int
-fdattach(struct isa_device *dev)
+fdc_attach(device_t dev)
{
- unsigned fdt;
- fdu_t fdu;
- fdcu_t fdcu = dev->id_unit;
- fdc_p fdc = fdc_data + fdcu;
- fd_p fd;
-#ifdef PC98
- int fdsu;
-#else
- int fdsu, st0, st3, i;
-#endif
- struct isa_device *fdup;
-#ifndef PC98
- int ic_type = 0;
-#endif
-#ifdef DEVFS
- int mynor;
- int typemynor;
- int typesize;
-#endif
+ struct fdc_data *fdc = device_get_softc(dev);
+ fdcu_t fdcu = device_get_unit(dev);
- dev->id_ointr = fdintr;
fdc->fdcu = fdcu;
fdc->flags |= FDC_ATTACHED;
-#ifdef PC98
- fdc->dmachan = 2;
- if (fdc->dmachan != dev->id_drq) {
- dev->id_drq = fdc->dmachan;
- printf(" [dma is changed to #%d]", fdc->dmachan);
- }
+
/* Acquire the DMA channel forever, The driver will do the rest */
+ /* XXX should integrate with rman */
isa_dma_acquire(fdc->dmachan);
isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
fdc->state = DEVIDLE;
+
+#ifdef PC98
+ /* reset controller, turn motor off, clear fdout mirror reg */
fdc_reset(fdc);
#else
- fdc->dmachan = dev->id_drq;
- /* Acquire the DMA channel forever, The driver will do the rest */
- isa_dma_acquire(fdc->dmachan);
- isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
- fdc->state = DEVIDLE;
/* reset controller, turn motor off, clear fdout mirror reg */
outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
#endif
bufq_init(&fdc->head);
- /* check for each floppy drive */
- for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) {
- if (fdup->id_iobase != dev->id_iobase)
- continue;
- fdu = fdup->id_unit;
- fd = &fd_data[fdu];
- if (fdu >= (NFD))
- continue;
- fdsu = fdup->id_physid;
- /* look up what bios thinks we have */
- switch (fdu) {
+#ifdef FIFO_BEFORE_MOTORON
+ /* Hmm, this doesn't work here - is set_motor() magic? -Peter */
+ if (fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN
+ && enable_fifo(fdc) == 0) {
+ device_print_prettyname(dev);
+ printf("FIFO enabled, %d bytes threshold\n", fifo_threshold);
+ }
+#endif
+ /*
+ * Probe and attach any children as were configured above.
+ */
+ return (bus_generic_attach(dev));
+}
+
+static void
+fdc_print_child(device_t me, device_t child)
+{
+ printf(" at %s%d drive %d", device_get_name(me), device_get_unit(me),
+ *(int *)device_get_ivars(child));
+}
+
+static int
+fd_probe(device_t dev)
+{
+ int i;
+ u_int fdt, st0, st3;
+ struct fd_data *fd;
+ struct fdc_data *fdc;
+ fdsu_t fdsu;
+#ifndef FIFO_BEFORE_MOTORON
+ static int fd_fifo = 0;
+#endif
+
+ fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */
+ fd = device_get_softc(dev);
+ fdc = device_get_softc(device_get_parent(dev));
+
+ bzero(fd, sizeof *fd);
+ fd->dev = dev;
+ fd->fdc = fdc;
+ fd->fdsu = fdsu;
+ fd->fdu = device_get_unit(dev);
+
#ifdef PC98
- case 0: case 1: case 2: case 3:
- if ((PC98_SYSTEM_PARAMETER(0x5ae) >> fdu) & 0x01)
- fdt = FDT_144M;
+ /* look up what bios thinks we have */
+ switch (fd->fdu) {
+ case 0: case 1: case 2: case 3:
+ if ((PC98_SYSTEM_PARAMETER(0x5ae) >> fd->fdu) & 0x01)
+ fdt = FDT_144M;
#ifdef EPSON_NRDISK
- else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fdu) & 0x01) {
- fdt = FDT_12M;
- switch (epson_machine_id) {
- case 0x20: case 0x27:
- if ((PC98_SYSTEM_PARAMETER(0x488) >> fdu) & 0x01) {
- if (nrd_check_ready()) {
- nrd_LED_on();
- nrdu = fdu;
- }
- else fdt = FDT_NONE;
- }
+ else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fd->fdu) & 0x01) {
+ fdt = FDT_12M;
+ switch (epson_machine_id) {
+ case 0x20: case 0x27:
+ if ((PC98_SYSTEM_PARAMETER(0x488) >> fd->fdu) & 0x01) {
+ if (nrd_check_ready()) {
+ nrd_LED_on();
+ nrdu = fd->fdu;
+ } else {
+ fdt = FDT_NONE;
}
+ }
}
+ }
#else /* !EPSON_NRDISK */
- else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fdu) & 0x01) {
- fdt = FDT_12M;
- switch (epson_machine_id) {
- case 0x20: case 0x27:
- if ((PC98_SYSTEM_PARAMETER(0x488) >> fdu) & 0x01)
- fdt = FDT_NONE;
- }
+ else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fd->fdu) & 0x01) {
+ fdt = FDT_12M;
+ switch (epson_machine_id) {
+ case 0x20: case 0x27:
+ if ((PC98_SYSTEM_PARAMETER(0x488) >> fd->fdu) & 0x01)
+ fdt = FDT_NONE;
}
+ }
#endif /* EPSON_NRDISK */
- else fdt = FDT_NONE;
- break;
- default:
+ else
fdt = FDT_NONE;
- break;
+ break;
+ default:
+ fdt = FDT_NONE;
+ break;
+ }
#else
- case 0: if (dev->id_flags & FDC_PRETEND_D0)
- fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED;
- else
- fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
- break;
- case 1: fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
- break;
- default: fdt = RTCFDT_NONE;
- break;
+ /* look up what bios thinks we have */
+ switch (fd->fdu) {
+ case 0:
+ if (isa_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0)
+ fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED;
+ else
+ fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
+ break;
+ case 1:
+ fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
+ break;
+ default:
+ fdt = RTCFDT_NONE;
+ break;
+ }
#endif
- }
- /* is there a unit? */
+
+ /* is there a unit? */
#ifdef PC98
- if ((fdt == FDT_NONE)
+ if (fdt == FDT_NONE)
+ return (ENXIO);
#else
- if ((fdt == RTCFDT_NONE)
-#endif
- ) {
-#ifdef PC98
- fd->fdc = fdc;
+ if (fdt == RTCFDT_NONE)
+ return (ENXIO);
#endif
- fd->type = NO_TYPE;
- continue;
- }
#ifndef PC98
- /* select it */
- set_motor(fdcu, fdsu, TURNON);
- DELAY(1000000); /* 1 sec */
-
- if (ic_type == 0 &&
- fd_cmd(fdcu, 1, NE7CMD_VERSION, 1, &ic_type) == 0)
- {
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("fdc%d: ", fdcu);
-#endif
- ic_type = (u_char)ic_type;
- switch( ic_type ) {
- case 0x80:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("NEC 765\n");
-#endif
- fdc->fdct = FDC_NE765;
- break;
- case 0x81:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("Intel 82077\n");
-#endif
- fdc->fdct = FDC_I82077;
- break;
- case 0x90:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("NEC 72065B\n");
-#endif
- fdc->fdct = FDC_NE72065;
- break;
- default:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("unknown IC type %02x\n", ic_type);
+ /* select it */
+ set_motor(fdc, fdsu, TURNON);
+ DELAY(1000000); /* 1 sec */
+
+#ifndef FIFO_BEFORE_MOTORON
+ if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN
+ && enable_fifo(fdc) == 0) {
+ device_print_prettyname(device_get_parent(dev));
+ printf("FIFO enabled, %d bytes threshold\n", fifo_threshold);
+ }
+ fd_fifo = 1;
#endif
- fdc->fdct = FDC_UNKNOWN;
- break;
- }
- if (fdc->fdct != FDC_NE765 &&
- fdc->fdct != FDC_UNKNOWN &&
- enable_fifo(fdc) == 0) {
- printf("fdc%d: FIFO enabled", fdcu);
- printf(", %d bytes threshold\n",
- fifo_threshold);
- }
- }
- if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&
- (st3 & NE7_ST3_T0)) {
- /* if at track 0, first seek inwards */
- /* seek some steps: */
- (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0);
- DELAY(300000); /* ...wait a moment... */
- (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
- }
- /* If we're at track 0 first seek inwards. */
- if ((fd_sense_drive_status(fdc, &st3) == 0) &&
- (st3 & NE7_ST3_T0)) {
- /* Seek some steps... */
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
- /* ...wait a moment... */
- DELAY(300000);
- /* make ctrlr happy: */
- (void)fd_sense_int(fdc, 0, 0);
- }
+ if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0)
+ && (st3 & NE7_ST3_T0)) {
+ /* if at track 0, first seek inwards */
+ /* seek some steps: */
+ fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0);
+ DELAY(300000); /* ...wait a moment... */
+ fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
+ }
+
+ /* If we're at track 0 first seek inwards. */
+ if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) {
+ /* Seek some steps... */
+ if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
+ /* ...wait a moment... */
+ DELAY(300000);
+ /* make ctrlr happy: */
+ fd_sense_int(fdc, 0, 0);
}
+ }
- for(i = 0; i < 2; i++) {
- /*
- * we must recalibrate twice, just in case the
- * heads have been beyond cylinder 76, since most
- * FDCs still barf when attempting to recalibrate
- * more than 77 steps
- */
- /* go back to 0: */
- if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
- /* a second being enough for full stroke seek*/
- DELAY(i == 0? 1000000: 300000);
+ for (i = 0; i < 2; i++) {
+ /*
+ * we must recalibrate twice, just in case the
+ * heads have been beyond cylinder 76, since most
+ * FDCs still barf when attempting to recalibrate
+ * more than 77 steps
+ */
+ /* go back to 0: */
+ if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
+ /* a second being enough for full stroke seek*/
+ DELAY(i == 0 ? 1000000 : 300000);
- /* anything responding? */
- if (fd_sense_int(fdc, &st0, 0) == 0 &&
- (st0 & NE7_ST0_EC) == 0)
- break; /* already probed succesfully */
- }
+ /* anything responding? */
+ if (fd_sense_int(fdc, &st0, 0) == 0 &&
+ (st0 & NE7_ST0_EC) == 0)
+ break; /* already probed succesfully */
}
+ }
- set_motor(fdcu, fdsu, TURNOFF);
+ set_motor(fdc, fdsu, TURNOFF);
- if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
- continue;
+ if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
+ return (ENXIO);
+#endif /* PC98 */
+
+ fd->track = FD_NO_TRACK;
+ fd->fdc = fdc;
+ fd->fdsu = fdsu;
+ fd->options = 0;
+ callout_handle_init(&fd->toffhandle);
+ callout_handle_init(&fd->tohandle);
+
+#ifdef PC98
+ switch (fdt) {
+ case FDT_12M:
+#ifdef EPSON_NRDISK
+ if (fdu == nrdu) {
+ device_set_desc(dev, "EPSON RAM DRIVE");
+ nrd_LED_off();
+ } else
+ device_set_desc(dev, "1M/640M FDD");
+#else
+ device_set_desc(dev, "1M/640M FDD");
+#endif
+ fd->type = FD_1200;
+ fd->pc98_trans = 0;
+ break;
+ case FDT_144M:
+ device_set_desc(dev, "1.44M FDD");
+ fd->type = FD_1200;
+ fd->pc98_trans = 0;
+ outb(0x4be, (fd->fdu << 5) | 0x10);
+ break;
+ default:
+ return (ENXIO);
+ }
+#else
+ switch (fdt) {
+ case RTCFDT_12M:
+ device_set_desc(dev, "1200-KB 5.25\" drive");
+ fd->type = FD_1200;
+ break;
+ case RTCFDT_144M | RTCFDT_144M_PRETENDED:
+ device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive");
+ fdt = RTCFDT_144M;
+ fd->type = FD_1440;
+ case RTCFDT_144M:
+ device_set_desc(dev, "1440-KB 3.5\" drive");
+ fd->type = FD_1440;
+ break;
+ case RTCFDT_288M:
+ case RTCFDT_288M_1:
+ device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)");
+ fd->type = FD_1440;
+ break;
+ case RTCFDT_360K:
+ device_set_desc(dev, "360-KB 5.25\" drive");
+ fd->type = FD_360;
+ break;
+ case RTCFDT_720K:
+ printf("720-KB 3.5\" drive");
+ fd->type = FD_720;
+ break;
+ default:
+ return (ENXIO);
+ }
#endif
+ return (0);
+}
- fd->track = FD_NO_TRACK;
- fd->fdc = fdc;
- fd->fdsu = fdsu;
- fd->options = 0;
- callout_handle_init(&fd->toffhandle);
- callout_handle_init(&fd->tohandle);
- printf("fd%d: ", fdu);
-
- switch (fdt) {
+static int
+fd_attach(device_t dev)
+{
+ struct fd_data *fd;
+
+ fd = device_get_softc(dev);
+
+#ifdef DEVFS /* XXX bitrot */
+ mynor = fdu << 6;
+ fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK,
+ UID_ROOT, GID_OPERATOR, 0640,
+ "fd%d", fdu);
+ fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
+ UID_ROOT, GID_OPERATOR, 0640,
+ "rfd%d", fdu);
+ for (i = 1; i < 1 + NUMDENS; i++) {
+ /*
+ * XXX this and the lookup in Fdopen() should be
+ * data driven.
+ */
#ifdef PC98
+ switch (fd->type) {
case FDT_12M:
-#ifdef EPSON_NRDISK
- if (fdu == nrdu) {
- printf("EPSON RAM DRIVE\n");
- nrd_LED_off();
- }
- else printf("1M/640M FDD\n");
-#else /* !EPSON_NRDISK */
- printf("1M/640K FDD\n");
-#endif /* EPSON_NRDISK */
- fd->type = FD_1200;
- fd->pc98_trans = 0;
+ if (i != FD_1200 && i != FD_1232
+ && i != FD_720 && i != FD_640)
+ continue;
break;
case FDT_144M:
- printf("1.44M FDD\n");
- fd->type = FD_1200;
- fd->pc98_trans = 0;
- outb(0x4be, (fdu << 5) | 0x10);
+ if (i != FD_1200 && i != FD_1232
+ && i != FD_720 && i != FD_640
+ && i != FD_1440)
+ continue;
break;
+ }
#else
- case RTCFDT_12M:
- printf("1.2MB 5.25in\n");
- fd->type = FD_1200;
+ switch (fd->type) {
+ case FD_360:
+ if (i != FD_360)
+ continue;
break;
- case RTCFDT_144M | RTCFDT_144M_PRETENDED:
- printf("config-pretended ");
- fdt = RTCFDT_144M;
- /* fallthrough */
- case RTCFDT_144M:
- printf("1.44MB 3.5in\n");
- fd->type = FD_1440;
+ case FD_720:
+ if (i != FD_720 && i != FD_800 && i != FD_820)
+ continue;
break;
- case RTCFDT_288M:
- case RTCFDT_288M_1:
- printf("2.88MB 3.5in - 1.44MB mode\n");
- fd->type = FD_1440;
+ case FD_1200:
+ if (i != FD_360 && i != FD_720 && i != FD_800
+ && i != FD_820 && i != FD_1200
+ && i != FD_1440 && i != FD_1480)
+ continue;
break;
- case RTCFDT_360K:
- printf("360KB 5.25in\n");
- fd->type = FD_360;
+ case FD_1440:
+ if (i != FD_720 && i != FD_800 && i != FD_820
+ && i != FD_1200 && i != FD_1440
+ && i != FD_1480 && i != FD_1720)
+ continue;
break;
- case RTCFDT_720K:
- printf("720KB 3.5in\n");
- fd->type = FD_720;
- break;
-#endif
- default:
- printf("unknown\n");
- fd->type = NO_TYPE;
- continue;
}
-#ifdef DEVFS
- mynor = fdu << 6;
- fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640,
- "fd%d", fdu);
- fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640,
- "rfd%d", fdu);
- for (i = 1; i < 1 + NUMDENS; i++) {
- /*
- * XXX this and the lookup in Fdopen() should be
- * data driven.
- */
-#ifdef PC98
- switch (fdt) {
- case FDT_12M:
- if (i != FD_1200 && i != FD_1232
- && i != FD_720 && i != FD_640)
- continue;
- break;
- case FDT_144M:
- if (i != FD_1200 && i != FD_1232
- && i != FD_720 && i != FD_640
- && i != FD_1440)
- continue;
- break;
- }
-#else
- switch (fd->type) {
- case FD_360:
- if (i != FD_360)
- continue;
- break;
- case FD_720:
- if (i != FD_720 && i != FD_800 && i != FD_820)
- continue;
- break;
- case FD_1200:
- if (i != FD_360 && i != FD_720 && i != FD_800
- && i != FD_820 && i != FD_1200
- && i != FD_1440 && i != FD_1480)
- continue;
- break;
- case FD_1440:
- if (i != FD_720 && i != FD_800 && i != FD_820
- && i != FD_1200 && i != FD_1440
- && i != FD_1480 && i != FD_1720)
- continue;
- break;
- }
#endif
#ifdef PC98
- if (i == FD_1232)
- typesize = fd_types[i - 1].size;
- else
- typesize = fd_types[i - 1].size / 2;
-#else
+ if (i == FD_1232)
+ typesize = fd_types[i - 1].size;
+ else
typesize = fd_types[i - 1].size / 2;
- /*
- * XXX all these conversions give bloated code and
- * confusing names.
- */
- if (typesize == 1476)
- typesize = 1480;
- if (typesize == 1722)
- typesize = 1720;
-#endif
- typemynor = mynor | i;
- fd->bdevs[i] =
- devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640,
- "fd%d.%d", fdu, typesize);
- fd->cdevs[i] =
- devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640,
- "rfd%d.%d", fdu, typesize);
- }
-
- for (i = 0; i < MAXPARTITIONS; i++) {
- fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0],
- "fd%d%c", fdu, 'a' + i);
- fd->cdevs[1 + NUMDENS + i] =
- devfs_makelink(fd->cdevs[0],
- "rfd%d%c", fdu, 'a' + i);
- }
-#endif /* DEVFS */
+#else
+ typesize = fd_types[i - 1].size / 2;
/*
- * Export the drive to the devstat interface.
+ * XXX all these conversions give bloated code and
+ * confusing names.
*/
- devstat_add_entry(&fd->device_stats, "fd",
- fdu, 512,
- DEVSTAT_NO_ORDERED_TAGS,
- DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER,
- DEVSTAT_PRIORITY_FD);
-
+ if (typesize == 1476)
+ typesize = 1480;
+ if (typesize == 1722)
+ typesize = 1720;
+#endif
+ typemynor = mynor | i;
+ fd->bdevs[i] =
+ devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK,
+ UID_ROOT, GID_OPERATOR, 0640,
+ "fd%d.%d", fdu, typesize);
+ fd->cdevs[i] =
+ devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR,
+ UID_ROOT, GID_OPERATOR, 0640,
+ "rfd%d.%d", fdu, typesize);
}
- return (1);
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0],
+ "fd%d%c", fdu, 'a' + i);
+ fd->cdevs[1 + NUMDENS + i] =
+ devfs_makelink(fd->cdevs[0],
+ "rfd%d%c", fdu, 'a' + i);
+ }
+#endif /* DEVFS */
+ /*
+ * Export the drive to the devstat interface.
+ */
+ devstat_add_entry(&fd->device_stats, device_get_name(dev),
+ device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS,
+ DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER,
+ DEVSTAT_PRIORITY_FD);
+ return (0);
}
-
-
#ifdef FDC_YE
/*
* this is a subset of fdattach() optimized for the Y-E Data
@@ -1307,9 +1377,9 @@ static int yeattach(struct isa_device *dev)
/* remember to not deselect the drive we're working on */
/****************************************************************************/
static void
-set_motor(fdcu_t fdcu, int fdsu, int turnon)
+set_motor(struct fdc_data *fdc, int fdsu, int turnon)
{
- int fdout = fdc_data[fdcu].fdout;
+ int fdout = fdc->fdout;
int needspecify = 0;
#ifdef PC98
@@ -1335,12 +1405,11 @@ set_motor(fdcu_t fdcu, int fdsu, int turnon)
}
#endif
- outb(fdc_data[fdcu].baseport+FDOUT, fdout);
- DELAY(10);
- fdc_data[fdcu].fdout = fdout;
+ outb(fdc->baseport+FDOUT, fdout);
+ fdc->fdout = fdout;
TRACE1("[0x%x->FDOUT]", fdout);
- if(needspecify) {
+ if (needspecify) {
/*
* XXX
* special case: since we have just woken up the FDC
@@ -1348,81 +1417,75 @@ set_motor(fdcu_t fdcu, int fdsu, int turnon)
* be accepted, and do not test for a timeout
*/
#ifdef PC98
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
+ (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
0);
#else
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
+ (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
0);
#endif
- if (fdc_data[fdcu].flags & FDC_HAS_FIFO)
- (void) enable_fifo(&fdc_data[fdcu]);
-
+ if (fdc->flags & FDC_HAS_FIFO)
+ (void) enable_fifo(fdc);
}
}
static void
-fd_turnoff(void *arg1)
+fd_turnoff(void *xfd)
{
- fdu_t fdu = (fdu_t)arg1;
int s;
- fd_p fd = fd_data + fdu;
+ fd_p fd = xfd;
- TRACE1("[fd%d: turnoff]", fdu);
+ TRACE1("[fd%d: turnoff]", fd->fdu);
/*
* Don't turn off the motor yet if the drive is active.
* XXX shouldn't even schedule turnoff until drive is inactive
* and nothing is queued on it.
*/
- if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fdu) {
- fd->toffhandle = timeout(fd_turnoff, arg1, 4 * hz);
+ if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) {
+ fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);
return;
}
s = splbio();
fd->flags &= ~FD_MOTOR;
- set_motor(fd->fdc->fdcu, fd->fdsu, TURNOFF);
+ set_motor(fd->fdc, fd->fdsu, TURNOFF);
splx(s);
}
static void
-fd_motor_on(void *arg1)
+fd_motor_on(void *xfd)
{
- fdu_t fdu = (fdu_t)arg1;
int s;
+ fd_p fd = xfd;
- fd_p fd = fd_data + fdu;
s = splbio();
fd->flags &= ~FD_MOTOR_WAIT;
if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT))
{
- fdintr(fd->fdc->fdcu);
+ fdc_intr(fd->fdc);
}
splx(s);
}
static void
-fd_turnon(fdu_t fdu)
+fd_turnon(fd_p fd)
{
- fd_p fd = fd_data + fdu;
if(!(fd->flags & FD_MOTOR))
{
fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT);
- set_motor(fd->fdc->fdcu, fd->fdsu, TURNON);
- timeout(fd_motor_on, (caddr_t)fdu, hz); /* in 1 sec its ok */
+ set_motor(fd->fdc, fd->fdsu, TURNON);
+ timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */
}
}
static void
fdc_reset(fdc_p fdc)
{
- fdcu_t fdcu = fdc->fdcu;
-
/* Try a reset, keep motor on */
#ifdef PC98
- set_density(fdcu, 0);
+ set_density(fdc);
if (pc98_machine_type & M_EPSON_PC98)
outb(fdc->baseport + FDOUT, 0xe8);
else
@@ -1444,11 +1507,11 @@ fdc_reset(fdc_p fdc)
/* XXX after a reset, silently believe the FDC will accept commands */
#ifdef PC98
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
+ (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
0);
#else
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
+ (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
0);
#endif
@@ -1460,16 +1523,16 @@ fdc_reset(fdc_p fdc)
/* fdc in/out */
/****************************************************************************/
int
-in_fdc(fdcu_t fdcu)
+in_fdc(struct fdc_data *fdc)
{
- int baseport = fdc_data[fdcu].baseport;
+ int baseport = fdc->baseport;
int i, j = 100000;
while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM))
!= (NE7_DIO|NE7_RQM) && j-- > 0)
if (i == NE7_RQM)
- return fdc_err(fdcu, "ready for output in input\n");
+ return fdc_err(fdc, "ready for output in input\n");
if (j <= 0)
- return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0);
+ return fdc_err(fdc, bootverbose? "input ready timeout\n": 0);
#ifdef FDC_DEBUG
i = inb(baseport+FDDATA);
TRACE1("[FDDATA->0x%x]", (unsigned char)i);
@@ -1483,16 +1546,16 @@ in_fdc(fdcu_t fdcu)
* fd_in: Like in_fdc, but allows you to see if it worked.
*/
static int
-fd_in(fdcu_t fdcu, int *ptr)
+fd_in(struct fdc_data *fdc, int *ptr)
{
- int baseport = fdc_data[fdcu].baseport;
+ int baseport = fdc->baseport;
int i, j = 100000;
while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM))
!= (NE7_DIO|NE7_RQM) && j-- > 0)
if (i == NE7_RQM)
- return fdc_err(fdcu, "ready for output in input\n");
+ return fdc_err(fdc, "ready for output in input\n");
if (j <= 0)
- return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0);
+ return fdc_err(fdc, bootverbose? "input ready timeout\n": 0);
#ifdef FDC_DEBUG
i = inb(baseport+FDDATA);
TRACE1("[FDDATA->0x%x]", (unsigned char)i);
@@ -1507,21 +1570,21 @@ fd_in(fdcu_t fdcu, int *ptr)
}
int
-out_fdc(fdcu_t fdcu, int x)
+out_fdc(struct fdc_data *fdc, int x)
{
- int baseport = fdc_data[fdcu].baseport;
+ int baseport = fdc->baseport;
int i;
/* Check that the direction bit is set */
i = 100000;
while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0);
- if (i <= 0) return fdc_err(fdcu, "direction bit not set\n");
+ if (i <= 0) return fdc_err(fdc, "direction bit not set\n");
/* Check that the floppy controller is ready for a command */
i = 100000;
while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0);
if (i <= 0)
- return fdc_err(fdcu, bootverbose? "output ready timeout\n": 0);
+ return fdc_err(fdc, bootverbose? "output ready timeout\n": 0);
/* Send the command and return */
outb(baseport+FDDATA, x);
@@ -1537,37 +1600,38 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
{
fdu_t fdu = FDUNIT(minor(dev));
int type = FDTYPE(minor(dev));
+ fd_p fd;
fdc_p fdc;
/* check bounds */
- if (fdu >= NFD)
- return(ENXIO);
- fdc = fd_data[fdu].fdc;
- if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE))
- return(ENXIO);
+ if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0)
+ return (ENXIO);
+ fdc = fd->fdc;
+ if ((fdc == NULL) || (fd->type == NO_TYPE))
+ return (ENXIO);
if (type > NUMDENS)
- return(ENXIO);
+ return (ENXIO);
#ifdef PC98
if (pc98_fd_check_ready(fdu) == -1)
return(EIO);
#endif
if (type == 0)
- type = fd_data[fdu].type;
+ type = fd->type;
#ifndef PC98
else {
/*
* For each type of basic drive, make sure we are trying
* to open a type it can do,
*/
- if (type != fd_data[fdu].type) {
- switch (fd_data[fdu].type) {
+ if (type != fd->type) {
+ switch (fd->type) {
case FD_360:
- return(ENXIO);
+ return (ENXIO);
case FD_720:
if ( type != FD_820
&& type != FD_800
)
- return(ENXIO);
+ return (ENXIO);
break;
case FD_1200:
switch (type) {
@@ -1607,9 +1671,10 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
}
}
#endif
- fd_data[fdu].ft = fd_types + type - 1;
- fd_data[fdu].flags |= FD_OPEN;
-
+ fd->ft = fd_types + type - 1;
+ fd->flags |= FD_OPEN;
+ device_busy(fd->dev);
+ device_busy(fd->fdc->fdc_dev);
return 0;
}
@@ -1617,11 +1682,13 @@ int
fdclose(dev_t dev, int flags, int mode, struct proc *p)
{
fdu_t fdu = FDUNIT(minor(dev));
+ struct fd_data *fd;
- fd_data[fdu].flags &= ~FD_OPEN;
- fd_data[fdu].options &= ~FDOPT_NORETRY;
+ fd = devclass_get_softc(fd_devclass, fdu);
+ fd->flags &= ~FD_OPEN;
+ fd->options &= ~FDOPT_NORETRY;
- return(0);
+ return (0);
}
static int
@@ -1645,16 +1712,17 @@ fdstrategy(struct buf *bp)
{
unsigned nblocks, blknum, cando;
int s;
- fdcu_t fdcu;
fdu_t fdu;
fdc_p fdc;
fd_p fd;
size_t fdblk;
fdu = FDUNIT(minor(bp->b_dev));
- fd = &fd_data[fdu];
+ fd = devclass_get_softc(fd_devclass, fdu);
+ if (fd == 0)
+ panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)",
+ (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev));
fdc = fd->fdc;
- fdcu = fdc->fdcu;
#ifdef FDC_YE
if (fd->type == NO_TYPE) {
bp->b_error = ENXIO;
@@ -1669,7 +1737,7 @@ fdstrategy(struct buf *bp)
fdblk = 128 << (fd->ft->secsize);
if (!(bp->b_flags & B_FORMAT)) {
- if ((fdu >= NFD) || (bp->b_blkno < 0)) {
+ if (bp->b_blkno < 0) {
printf(
"fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n",
fdu, (u_long)bp->b_blkno, bp->b_bcount);
@@ -1699,14 +1767,6 @@ fdstrategy(struct buf *bp)
blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk;
nblocks = fd->ft->size;
bp->b_resid = 0;
-#ifdef PC98
-#define B_XXX2 0x8000000
- if (bp->b_flags & B_XXX2) {
- blknum *= 2;
- bp->b_blkno *= 2;
- bp->b_flags &= ~B_XXX2;
- }
-#endif
if (blknum + (bp->b_bcount / fdblk) > nblocks) {
if (blknum <= nblocks) {
cando = (nblocks - blknum) * fdblk;
@@ -1722,12 +1782,12 @@ fdstrategy(struct buf *bp)
bp->b_pblkno = bp->b_blkno;
s = splbio();
bufqdisksort(&fdc->head, bp);
- untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); /* a good idea */
+ untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */
/* Tell devstat we are starting on the transaction */
devstat_start_transaction(&fd->device_stats);
- fdstart(fdcu);
+ fdstart(fdc);
splx(s);
return;
@@ -1745,27 +1805,25 @@ bad:
* will pick up our work when the present work completes *
\***************************************************************/
static void
-fdstart(fdcu_t fdcu)
+fdstart(struct fdc_data *fdc)
{
int s;
s = splbio();
- if(fdc_data[fdcu].state == DEVIDLE)
+ if(fdc->state == DEVIDLE)
{
- fdintr(fdcu);
+ fdc_intr(fdc);
}
splx(s);
}
static void
-fd_iotimeout(void *arg1)
+fd_iotimeout(void *xfdc)
{
fdc_p fdc;
- fdcu_t fdcu;
int s;
- fdcu = (fdcu_t)arg1;
- fdc = fdc_data + fdcu;
+ fdc = xfdc;
TRACE1("fd%d[fd_iotimeout()]", fdc->fdu);
/*
@@ -1783,19 +1841,18 @@ fd_iotimeout(void *arg1)
fdc->status[0] = NE7_ST0_IC_IV;
fdc->flags &= ~FDC_STAT_VALID;
fdc->state = IOTIMEDOUT;
- fdintr(fdcu);
+ fdc_intr(fdc);
splx(s);
}
/* just ensure it has the right spl */
static void
-fd_pseudointr(void *arg1)
+fd_pseudointr(void *xfdc)
{
- fdcu_t fdcu = (fdcu_t)arg1;
int s;
s = splbio();
- fdintr(fdcu);
+ fdc_intr(xfdc);
splx(s);
}
@@ -1805,11 +1862,11 @@ fd_pseudointr(void *arg1)
* ALWAYS called at SPLBIO *
\***********************************************************************/
static void
-fdintr(fdcu_t fdcu)
+fdc_intr(void *xfdc)
{
- fdc_p fdc = fdc_data + fdcu;
- while(fdstate(fdcu, fdc))
- ;
+ fdc_p fdc = xfdc;
+ while(fdstate(fdc))
+ ;
}
#ifdef FDC_YE
@@ -1849,7 +1906,7 @@ static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count)
* if it returns a non zero value, it should be called again immediatly *
\***********************************************************************/
static int
-fdstate(fdcu_t fdcu, fdc_p fdc)
+fdstate(fdc_p fdc)
{
int read, format, head, i, sec = 0, sectrac, st0, cyl, st3;
unsigned blknum = 0, b_cylinder = 0;
@@ -1873,26 +1930,25 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
* Force into the IDLE state, *
\***********************************************/
fdc->state = DEVIDLE;
- if(fdc->fd)
- {
- printf("fd%d: unexpected valid fd pointer\n",
- fdc->fdu);
+ if (fdc->fd) {
+ device_print_prettyname(fdc->fdc_dev);
+ printf("unexpected valid fd pointer\n");
fdc->fd = (fd_p) 0;
fdc->fdu = -1;
}
- TRACE1("[fdc%d IDLE]", fdcu);
- return(0);
+ TRACE1("[fdc%d IDLE]", fdc->fdcu);
+ return (0);
}
fdu = FDUNIT(minor(bp->b_dev));
- fd = fd_data + fdu;
+ fd = devclass_get_softc(fd_devclass, fdu);
fdblk = 128 << fd->ft->secsize;
- if (fdc->fd && (fd != fdc->fd))
- {
- printf("fd%d: confused fd pointers\n", fdu);
+ if (fdc->fd && (fd != fdc->fd)) {
+ device_print_prettyname(fd->dev);
+ printf("confused fd pointers\n");
}
read = bp->b_flags & B_READ;
format = bp->b_flags & B_FORMAT;
- if(format) {
+ if (format) {
finfo = (struct fd_formb *)bp->b_data;
fd->skip = (char *)&(finfo->fd_formb_cylno(0))
- (char *)finfo;
@@ -1905,8 +1961,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
TRACE1("fd%d", fdu);
TRACE1("[%s]", fdstates[fdc->state]);
TRACE1("(0x%x)", fd->flags);
- untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle);
- fd->toffhandle = timeout(fd_turnoff, (caddr_t)fdu, 4 * hz);
+ untimeout(fd_turnoff, fd, fd->toffhandle);
+ fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);
switch (fdc->state)
{
case DEVIDLE:
@@ -1919,7 +1975,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
pc98_trans = fd->ft->trans;
if (pc98_trans_prev != pc98_trans) {
int i;
- set_density(fdcu, fdu);
+ set_density(fdc);
for (i = 0; i < 10; i++) {
outb(0x5f, 0);
outb(0x5f, 0);
@@ -1943,10 +1999,9 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
* If the next drive has a motor startup pending, then *
* it will start up in its own good time *
\*******************************************************/
- if(fd->flags & FD_MOTOR_WAIT)
- {
+ if(fd->flags & FD_MOTOR_WAIT) {
fdc->state = MOTORWAIT;
- return(0); /* come back later */
+ return (0); /* come back later */
}
/*******************************************************\
* Maybe if it's not starting, it SHOULD be starting *
@@ -1968,12 +2023,12 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
if (!(fd->flags & FD_MOTOR))
{
fdc->state = MOTORWAIT;
- fd_turnon(fdu);
- return(0);
+ fd_turnon(fd);
+ return (0);
}
else /* at least make sure we are selected */
{
- set_motor(fdcu, fd->fdsu, TURNON);
+ set_motor(fdc, fd->fdsu, TURNON);
}
#endif
if (fdc->flags & FDC_NEEDS_RESET) {
@@ -1991,7 +2046,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
#ifdef PC98
pc98_fd_check_ready(fdu);
#endif
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK,
+ if (fd_cmd(fdc, 3, NE7CMD_SEEK,
fd->fdsu, b_cylinder * fd->ft->steptrac,
0))
{
@@ -2000,20 +2055,19 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
* the FDC went off to the Saints...
*/
fdc->retry = 6; /* try a reset */
- return(retrier(fdcu));
+ return(retrier(fdc));
}
fd->track = FD_NO_TRACK;
fdc->state = SEEKWAIT;
return(0); /* will return later */
case SEEKWAIT:
/* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, hz / 16);
+ timeout(fd_pseudointr, fdc, hz / 16);
fdc->state = SEEKCOMPLETE;
return(0); /* will return later */
case SEEKCOMPLETE : /* SEEK DONE, START DMA */
/* Make sure seek really happened*/
- if(fd->track == FD_NO_TRACK)
- {
+ if(fd->track == FD_NO_TRACK) {
int descyl = b_cylinder * fd->ft->steptrac;
do {
/*
@@ -2045,8 +2099,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
return 0; /* hope for a real intr */
} while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
- if (0 == descyl)
- {
+ if (0 == descyl) {
int failed = 0;
/*
* seek to cyl 0 requested; make sure we are
@@ -2064,25 +2117,23 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
failed = 1;
}
- if (failed)
- {
+ if (failed) {
if(fdc->retry < 3)
fdc->retry = 3;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
}
#ifdef EPSON_NRDISK
if (fdu == nrdu) cyl = descyl;
#endif
- if (cyl != descyl)
- {
+ if (cyl != descyl) {
printf(
"fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
fdu, descyl, cyl, st0);
if (fdc->retry < 3)
fdc->retry = 3;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
}
@@ -2100,6 +2151,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
head = sec / sectrac;
sec = sec % sectrac + 1;
fd->hddrv = ((head&1)<<2)+fdu;
+
if(format || !read)
{
/* make sure the drive is writable */
@@ -2110,7 +2162,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
format ? bp->b_bcount : fdblk,
fdc->dmachan);
fdc->retry = 6; /* reset the beast */
- return(retrier(fdcu));
+ return (retrier(fdc));
}
if(st3 & NE7_ST3_WP)
{
@@ -2133,8 +2185,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
}
}
- if(format)
- {
+ if (format) {
#ifdef FDC_YE
if (fdc->flags & FDC_PCMCIA)
(void)fdcpio(fdcu,bp->b_flags,
@@ -2142,25 +2193,19 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
bp->b_bcount);
#endif
/* formatting */
- if(fd_cmd(fdcu, 6,
- NE7CMD_FORMAT,
- head << 2 | fdu,
+ if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu,
finfo->fd_formb_secshift,
finfo->fd_formb_nsecs,
finfo->fd_formb_gaplen,
- finfo->fd_formb_fillbyte,
- 0))
- {
+ finfo->fd_formb_fillbyte, 0)) {
/* controller fell over */
isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
format ? bp->b_bcount : fdblk,
fdc->dmachan);
fdc->retry = 6;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
- }
- else
- {
+ } else {
#ifdef FDC_YE
if (fdc->flags & FDC_PCMCIA) {
/*
@@ -2179,7 +2224,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdblk);
}
#endif
- if (fd_cmd(fdcu, 9,
+ if (fd_cmd(fdc, 9,
(read ? NE7CMD_READ : NE7CMD_WRITE),
head << 2 | fdu, /* head & unit */
fd->track, /* track */
@@ -2189,14 +2234,13 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
sectrac, /* sectors/track */
fd->ft->gap, /* gap size */
fd->ft->datalen, /* data length */
- 0))
- {
+ 0)) {
/* the beast is sleeping again */
isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
format ? bp->b_bcount : fdblk,
fdc->dmachan);
fdc->retry = 6;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
}
#ifdef FDC_YE
@@ -2218,8 +2262,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
*/
#endif
fdc->state = IOCOMPLETE;
- fd->tohandle = timeout(fd_iotimeout, (caddr_t)fdcu, hz);
- return(0); /* will return later */
+ fd->tohandle = timeout(fd_iotimeout, fdc, hz);
+ return (0); /* will return later */
#ifdef EPSON_NRDISK
}
else {
@@ -2263,19 +2307,18 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
case IOCOMPLETE: /* IO DONE, post-analyze */
#ifdef EPSON_NRDISK
if (fdu != nrdu)
- untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle);
+ untimeout(fd_iotimeout, fdc, fd->tohandle);
#else
- untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle);
+ untimeout(fd_iotimeout, fdc, fd->tohandle);
#endif
- if (fd_read_status(fdc, fd->fdsu))
- {
+ if (fd_read_status(fdc, fd->fdsu)) {
isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
format ? bp->b_bcount : fdblk,
fdc->dmachan);
if (fdc->retry < 6)
fdc->retry = 6; /* force a reset */
- return retrier(fdcu);
+ return (retrier(fdc));
}
fdc->state = IOTIMEDOUT;
@@ -2295,8 +2338,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
}
else nrd_LED_off();
#endif /* EPSON_NRDISK */
- if (fdc->status[0] & NE7_ST0_IC)
- {
+ if (fdc->status[0] & NE7_ST0_IC) {
if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
&& fdc->status[1] & NE7_ST1_OR) {
/*
@@ -2316,17 +2358,14 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
&& fdc->status[2] & NE7_ST2_WC
&& fdc->retry < 3)
fdc->retry = 3; /* force recalibrate */
- return(retrier(fdcu));
+ return (retrier(fdc));
}
/* All OK */
fd->skip += fdblk;
- if (!format && fd->skip < bp->b_bcount - bp->b_resid)
- {
+ if (!format && fd->skip < bp->b_bcount - bp->b_resid) {
/* set up next transfer */
fdc->state = DOSEEK;
- }
- else
- {
+ } else {
/* ALL DONE */
fd->skip = 0;
fdc->bp = NULL;
@@ -2341,7 +2380,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdc->fdu = -1;
fdc->state = FINDWORK;
}
- return(1);
+ return (1);
case RESETCTLR:
fdc_reset(fdc);
fdc->retry++;
@@ -2360,21 +2399,18 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
#ifdef PC98
pc98_fd_check_ready(fdu);
#endif
- if(fd_cmd(fdcu,
- 2, NE7CMD_RECAL, fdu,
- 0)) /* Recalibrate Function */
- {
+ if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) {
/* arrgl */
fdc->retry = 6;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
fdc->state = RECALWAIT;
- return(0); /* will return later */
+ return (0); /* will return later */
case RECALWAIT:
/* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, hz / 8);
+ timeout(fd_pseudointr, fdc, hz / 8);
fdc->state = RECALCOMPLETE;
- return(0); /* will return later */
+ return (0); /* will return later */
case RECALCOMPLETE:
do {
/*
@@ -2406,16 +2442,16 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
printf("fd%d: recal failed ST0 %b cyl %d\n",
fdu, st0, NE7_ST0BITS, cyl);
if(fdc->retry < 3) fdc->retry = 3;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
fd->track = 0;
/* Seek (probably) necessary */
fdc->state = DOSEEK;
- return(1); /* will return immediatly */
+ return (1); /* will return immediatly */
case MOTORWAIT:
if(fd->flags & FD_MOTOR_WAIT)
{
- return(0); /* time's not up yet */
+ return (0); /* time's not up yet */
}
if (fdc->flags & FDC_NEEDS_RESET) {
fdc->state = RESETCTLR;
@@ -2428,9 +2464,10 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
*/
fdc->state = STARTRECAL;
}
- return(1); /* will return immediatly */
+ return (1); /* will return immediatly */
default:
- printf("fdc%d: Unexpected FD int->", fdcu);
+ device_print_prettyname(fdc->fdc_dev);
+ printf("unexpected FD int->");
if (fd_read_status(fdc, fd->fdsu) == 0)
printf("FDC status :%x %x %x %x %x %x %x ",
fdc->status[0],
@@ -2445,28 +2482,31 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
if (fd_sense_int(fdc, &st0, &cyl) != 0)
{
printf("[controller is dead now]\n");
- return(0);
+ return (0);
}
printf("ST0 = %x, PCN = %x\n", st0, cyl);
- return(0);
+ return (0);
}
/*XXX confusing: some branches return immediately, others end up here*/
- return(1); /* Come back immediatly to new state */
+ return (1); /* Come back immediatly to new state */
}
static int
-retrier(fdcu)
- fdcu_t fdcu;
+retrier(struct fdc_data *fdc)
{
- fdc_p fdc = fdc_data + fdcu;
register struct buf *bp;
+ struct fd_data *fd;
+ int fdu;
bp = fdc->bp;
- if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY)
+ /* XXX shouldn't this be cached somewhere? */
+ fdu = FDUNIT(minor(bp->b_dev));
+ fd = devclass_get_softc(fd_devclass, fdu);
+ if (fd->options & FDOPT_NORETRY)
goto fail;
- switch(fdc->retry)
- {
+
+ switch (fdc->retry) {
case 0: case 1: case 2:
fdc->state = SEEKCOMPLETE;
break;
@@ -2519,10 +2559,10 @@ retrier(fdcu)
fdc->flags |= FDC_NEEDS_RESET;
fdc->fd = (fd_p) 0;
fdc->fdu = -1;
- return(1);
+ return (1);
}
fdc->retry++;
- return(1);
+ return (1);
}
static int
@@ -2539,7 +2579,7 @@ fdformat(dev, finfo, p)
size_t fdblk;
fdu = FDUNIT(minor(dev));
- fd = &fd_data[fdu];
+ fd = devclass_get_softc(fd_devclass, fdu);
fdblk = 128 << fd->ft->secsize;
/* set up a buffer header for fdstrategy() */
@@ -2570,20 +2610,19 @@ fdformat(dev, finfo, p)
/* ...and wait for it to complete */
s = splbio();
- while(!(bp->b_flags & B_DONE))
- {
+ while(!(bp->b_flags & B_DONE)) {
rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz);
- if(rv == EWOULDBLOCK)
+ if (rv == EWOULDBLOCK)
break;
}
splx(s);
- if(rv == EWOULDBLOCK) {
+ if (rv == EWOULDBLOCK) {
/* timed out */
rv = EIO;
biodone(bp);
}
- if(bp->b_flags & B_ERROR)
+ if (bp->b_flags & B_ERROR)
rv = bp->b_error;
/*
* allow the process to be swapped
@@ -2606,7 +2645,7 @@ fdioctl(dev, cmd, addr, flag, p)
struct proc *p;
{
fdu_t fdu = FDUNIT(minor(dev));
- fd_p fd = &fd_data[fdu];
+ fd_p fd = devclass_get_softc(fd_devclass, fdu);
size_t fdblk;
struct fd_type *fdt;
@@ -2617,15 +2656,14 @@ fdioctl(dev, cmd, addr, flag, p)
fdblk = 128 << fd->ft->secsize;
#ifdef PC98
- pc98_fd_check_ready(fdu);
+ pc98_fd_check_ready(fdu);
#endif
- switch (cmd)
- {
+ switch (cmd) {
case DIOCGDINFO:
bzero(buffer, sizeof (buffer));
dl = (struct disklabel *)buffer;
dl->d_secsize = fdblk;
- fdt = fd_data[FDUNIT(minor(dev))].ft;
+ fdt = fd->ft;
dl->d_secpercyl = fdt->size / fdt->tracks;
dl->d_type = DTYPE_FLOPPY;
@@ -2649,8 +2687,7 @@ fdioctl(dev, cmd, addr, flag, p)
break;
case DIOCWDINFO:
- if ((flag & FWRITE) == 0)
- {
+ if ((flag & FWRITE) == 0) {
error = EBADF;
break;
}
@@ -2665,9 +2702,9 @@ fdioctl(dev, cmd, addr, flag, p)
(struct disklabel *)buffer);
break;
case FD_FORM:
- if((flag & FWRITE) == 0)
+ if ((flag & FWRITE) == 0)
error = EBADF; /* must be opened for writing */
- else if(((struct fd_formb *)addr)->format_version !=
+ else if (((struct fd_formb *)addr)->format_version !=
FD_FORMAT_VERSION)
error = EINVAL; /* wrong version of formatting prog */
else
@@ -2680,7 +2717,7 @@ fdioctl(dev, cmd, addr, flag, p)
case FD_STYPE: /* set drive type */
/* this is considered harmful; only allow for superuser */
- if(suser(p->p_ucred, &p->p_acflag) != 0)
+ if (suser(p->p_ucred, &p->p_acflag) != 0)
return EPERM;
*fd->ft = *(struct fd_type *)addr;
break;
@@ -2700,22 +2737,62 @@ fdioctl(dev, cmd, addr, flag, p)
return (error);
}
+static device_method_t fdc_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, fdc_probe),
+ DEVMETHOD(device_attach, fdc_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),
-static fd_devsw_installed = 0;
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, fdc_print_child),
+ /* Our children never use any other bus interface methods. */
-static void fd_drvinit(void *notused )
-{
+ { 0, 0 }
+};
- if( ! fd_devsw_installed ) {
- cdevsw_add_generic(BDEV_MAJOR,CDEV_MAJOR, &fd_cdevsw);
- fd_devsw_installed = 1;
- }
-}
+static driver_t fdc_driver = {
+ "fdc",
+ fdc_methods,
+ DRIVER_TYPE_BIO,
+ sizeof(struct fdc_data)
+};
-SYSINIT(fddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,fd_drvinit,NULL)
+DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0);
+static device_method_t fd_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, fd_probe),
+ DEVMETHOD(device_attach, fd_attach),
+ DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX */
+ DEVMETHOD(device_resume, bus_generic_resume), /* XXX */
-#endif
+ { 0, 0 }
+};
+
+static driver_t fd_driver = {
+ "fd",
+ fd_methods,
+ DRIVER_TYPE_BIO,
+ sizeof(struct fd_data)
+};
+
+static struct cdevsw fd_cdevsw = {
+ Fdopen, fdclose, fdread, fdwrite,
+ fdioctl, nostop, nullreset, nodevtotty,
+ seltrue, nommap, fdstrategy, "fd",
+ NULL, -1, nodump, nopsize,
+ D_DISK, 0, -1
+};
+
+BDEV_DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, BDEV_MAJOR, CDEV_MAJOR,
+ fd_cdevsw, 0, 0);
+
+#endif /* NFDC > 0 */
/*
* Hello emacs, these are the
diff --git a/sys/pc98/cbus/gdc.c b/sys/pc98/cbus/gdc.c
index 6b4ac09..7f4570a 100644
--- a/sys/pc98/cbus/gdc.c
+++ b/sys/pc98/cbus/gdc.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pc98gdc.c,v 1.5 1999/02/06 09:30:19 kato Exp $
+ * $Id: pc98gdc.c,v 1.6 1999/03/02 12:34:24 kato Exp $
*/
#include "gdc.h"
@@ -52,8 +52,7 @@
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
-
-#include <i386/isa/isa_device.h>
+#include <isa/isavar.h>
#define TEXT_GDC IO_GDC1 /* 0x60 */
#define ROW 25
@@ -66,27 +65,36 @@
#define GDC_UNIT(dev) minor(dev)
#define GDC_MKMINOR(unit) (unit)
-static int gdcprobe(struct isa_device *dev);
-static int gdc_attach(struct isa_device *dev);
+typedef struct gdc_softc {
+ video_adapter_t *adp;
+} gdc_softc_t;
+
+#define GDC_SOFTC(unit) \
+ ((gdc_softc_t *)devclass_get_softc(gdc_devclass, unit))
+
+devclass_t gdc_devclass;
+
+static int gdcprobe(device_t dev);
+static int gdc_attach(device_t dev);
-struct isa_driver gdcdriver = {
- gdcprobe,
- gdc_attach,
+static device_method_t gdc_methods[] = {
+ DEVMETHOD(device_probe, gdcprobe),
+ DEVMETHOD(device_attach, gdc_attach),
+ { 0, 0 }
+};
+
+static driver_t gdcdriver = {
DRIVER_NAME,
- 0,
+ gdc_methods,
+ DRIVER_TYPE_TTY,
+ sizeof(gdc_softc_t),
};
-typedef struct gdc_softc {
- video_adapter_t *adp;
-} gdc_softc_t;
+DRIVER_MODULE(gdc, isa, gdcdriver, gdc_devclass, 0, 0);
static int gdc_probe_unit(int unit, gdc_softc_t *sc, int flags);
static int gdc_attach_unit(int unit, gdc_softc_t *sc, int flags);
-#define GDC_SOFTC(unit) (gdc_softc[unit])
-
-static gdc_softc_t *gdc_softc[NGDC];
-
#if FB_INSTALL_CDEV
static d_open_t gdcopen;
@@ -104,44 +112,22 @@ static struct cdevsw vga_cdevsw = {
#endif /* FB_INSTALL_CDEV */
static int
-gdcprobe(struct isa_device *dev)
+gdcprobe(device_t dev)
{
gdc_softc_t *sc;
- int error;
-
- if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
- return 0;
- sc = gdc_softc[dev->id_unit]
- = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
- if (sc == NULL)
- return 0;
-
- error = gdc_probe_unit(dev->id_unit, sc, dev->id_flags);
- if (error) {
- gdc_softc[dev->id_unit] = NULL;
- free(sc, M_DEVBUF);
- return 0;
- }
-
- dev->id_iobase = sc->adp->va_io_base;
- dev->id_maddr = (caddr_t)BIOS_PADDRTOVADDR(sc->adp->va_mem_base);
- dev->id_msize = sc->adp->va_mem_size;
- return sc->adp->va_io_size;
+ device_set_desc(dev, "Generic GDC");
+ sc = device_get_softc(dev);
+ return gdc_probe_unit(device_get_unit(dev), sc, isa_get_flags(dev));
}
static int
-gdc_attach(struct isa_device *dev)
+gdc_attach(device_t dev)
{
gdc_softc_t *sc;
- if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
- return 0;
- sc = gdc_softc[dev->id_unit];
- if (sc == NULL)
- return 0;
-
- return ((gdc_attach_unit(dev->id_unit, sc, dev->id_flags)) ? 0 : 1);
+ sc = device_get_softc(dev);
+ return gdc_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev));
}
static int
diff --git a/sys/pc98/cbus/pckbd.c b/sys/pc98/cbus/pckbd.c
index 731f463..a9d44f7 100644
--- a/sys/pc98/cbus/pckbd.c
+++ b/sys/pc98/cbus/pckbd.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pc98kbd.c,v 1.4 1999/01/19 14:08:04 kato Exp $
+ * $Id: pc98kbd.c,v 1.5 1999/03/10 14:51:53 kato Exp $
*/
#include "pckbd.h"
@@ -39,10 +39,13 @@
#include <sys/kernel.h>
#include <sys/conf.h>
#include <sys/proc.h>
+#include <sys/module.h>
#include <sys/tty.h>
#include <sys/fcntl.h>
-#include <sys/bus.h>
#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
#include <machine/resource.h>
@@ -51,6 +54,9 @@
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
+#include <isa/isavar.h>
+#include <machine/lock.h>
+
#ifdef __i386__
#include <i386/isa/isa_device.h>
#endif
@@ -76,23 +82,30 @@ typedef struct pckbd_softc {
} pckbd_softc_t;
#define PC98KBD_SOFTC(unit) \
- (((unit) >= NPCKBD) ? NULL : pckbd_softc[(unit)])
+ ((pckbd_softc_t)devclass_get_softc(pckbd_devclass, unit))
-static pckbd_softc_t *pckbd_softc[NPCKBD];
+static devclass_t pckbd_devclass;
-static int pckbdprobe(struct isa_device *dev);
-static int pckbdattach(struct isa_device *dev);
+static int pckbdprobe(device_t dev);
+static int pckbdattach(device_t dev);
+static void pckbd_isa_intr(void *arg);
-static ointhand2_t pckbd_isa_intr;
+static device_method_t pckbd_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pckbdprobe),
+ DEVMETHOD(device_attach, pckbdattach),
+ { 0, 0 }
+};
-/* driver declaration for isa_devtab_tty[] */
-struct isa_driver pckbddriver = {
- pckbdprobe,
- pckbdattach,
+static driver_t pckbd_driver = {
DRIVER_NAME,
- 0,
+ pckbd_methods,
+ DRIVER_TYPE_TTY,
+ sizeof(pckbd_softc_t),
};
+DRIVER_MODULE(pckbd, isa, pckbd_driver, pckbd_devclass, 0, 0);
+
static int pckbd_probe_unit(int unit, int port, int irq,
int flags);
static int pckbd_attach_unit(int unit, pckbd_softc_t *sc,
@@ -117,36 +130,41 @@ static struct cdevsw pckbd_cdevsw = {
#endif /* KBD_INSTALL_CDEV */
static int
-pckbdprobe(struct isa_device *dev)
+pckbdprobe(device_t dev)
{
- return ((pckbd_probe_unit(dev->id_unit, dev->id_iobase, dev->id_irq,
- dev->id_flags)) ? 0 : IO_KBDSIZE);
+ device_set_desc(dev, "PC-98 Keyboard");
+
+ return pckbd_probe_unit(device_get_unit(dev), isa_get_port(dev),
+ (1 << isa_get_irq(dev)), isa_get_flags(dev));
}
static int
-pckbdattach(struct isa_device *dev)
+pckbdattach(device_t dev)
{
- pckbd_softc_t *sc;
+ void *ih;
+ struct resource *res;
+ int zero = 0;
- if (dev->id_unit >= sizeof(pckbd_softc)/sizeof(pckbd_softc[0]))
- return 0;
- sc = pckbd_softc[dev->id_unit]
- = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
- if (sc == NULL)
- return 0;
+ pckbd_softc_t *sc = device_get_softc(dev);
bzero(sc, sizeof(*sc));
- dev->id_ointr = pckbd_isa_intr;
- return ((pckbd_attach_unit(dev->id_unit, sc, dev->id_iobase,
- dev->id_irq, dev->id_flags)) ? 0 : 1);
+ pckbd_attach_unit(device_get_unit(dev), sc, isa_get_port(dev),
+ (1 << isa_get_irq(dev)), isa_get_flags(dev));
+
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, 0ul, ~0ul, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ BUS_SETUP_INTR(device_get_parent(dev), dev, res, pckbd_isa_intr,
+ sc, &ih);
+
+ return (0);
}
static void
-pckbd_isa_intr(int unit)
+pckbd_isa_intr(void *arg)
{
- keyboard_t *kbd;
+ pckbd_softc_t *sc = arg;
+ keyboard_t *kbd = sc->kbd;
- kbd = pckbd_softc[unit]->kbd;
(*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
}
@@ -414,15 +432,14 @@ pckbd_configure(int flags)
{
keyboard_t *kbd;
int arg[2];
- struct isa_device *dev;
int i;
/* XXX: a kludge to obtain the device configuration flags */
- dev = find_isadev(isa_devtab_tty, &pckbddriver, 0);
- if (dev != NULL) {
- flags |= dev->id_flags;
+ if (resource_int_value(DRIVER_NAME, 0, "flags", &i) == 0) {
+ flags |= i;
/* if the driver is disabled, unregister the keyboard if any */
- if (!dev->id_enabled) {
+ if (resource_int_value(DRIVER_NAME, 0, "disabled", &i) == 0
+ && i != 0) {
i = kbd_find_keyboard(DRIVER_NAME, PC98KBD_DEFAULT);
if (i >= 0) {
kbd = kbd_get_keyboard(i);
diff --git a/sys/pc98/cbus/sio.c b/sys/pc98/cbus/sio.c
index 962d4f9..94adb71 100644
--- a/sys/pc98/cbus/sio.c
+++ b/sys/pc98/cbus/sio.c
@@ -31,16 +31,17 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.84 1999/04/01 13:44:15 kato Exp $
+ * $Id: sio.c,v 1.85 1999/04/03 15:51:14 kato Exp $
*/
#include "opt_comconsole.h"
#include "opt_compat.h"
#include "opt_ddb.h"
#include "opt_devfs.h"
-#include "opt_sio.h"
+/* #include "opt_sio.h" */
#include "sio.h"
-#include "pnp.h"
+/* #include "pnp.h" */
+#define NPNP 0
/*
* Serial driver, based on 386BSD-0.1 com driver.
@@ -141,6 +142,7 @@
#include <sys/malloc.h>
#include <sys/tty.h>
#include <sys/proc.h>
+#include <sys/module.h>
#include <sys/conf.h>
#include <sys/dkstat.h>
#include <sys/fcntl.h>
@@ -148,28 +150,32 @@
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <sys/sysctl.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
#ifdef DEVFS
#include <sys/devfsext.h>
#endif
#include <sys/timepps.h>
-#include <machine/clock.h>
-#include <machine/ipl.h>
-#ifndef SMP
-#include <machine/lock.h>
-#endif
-
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
-#include <i386/isa/icu.h>
#include <i386/isa/ic/i8251.h>
#else
-#include <i386/isa/isa.h>
+#include <isa/isareg.h>
+#endif
+#include <isa/isavar.h>
+#include <machine/lock.h>
+
+#include <machine/clock.h>
+#include <machine/ipl.h>
+#ifndef SMP
+#include <machine/lock.h>
#endif
-#include <i386/isa/isa_device.h>
-#include <i386/isa/sioreg.h>
-#include <i386/isa/intr_machdep.h>
+#include <machine/resource.h>
+
+#include <isa/sioreg.h>
#ifdef COM_ESP
#include <i386/isa/ic/esp.h>
@@ -179,6 +185,8 @@
#include <i386/isa/ic/rsa.h>
#endif
+#if 0
+
#include "card.h"
#if NCARD > 0
#include <sys/module.h>
@@ -190,6 +198,13 @@
#include <i386/isa/pnp.h>
#endif
+#endif
+
+#ifndef __i386__
+#define disable_intr() 0
+#define enable_intr() 0
+#endif
+
#ifdef SMP
#define disable_intr() COM_DISABLE_INTR()
#define enable_intr() COM_ENABLE_INTR()
@@ -219,22 +234,22 @@
/* checks in flags for multiport and which is multiport "master chip"
* for a given card
*/
-#define COM_ISMULTIPORT(dev) ((dev)->id_flags & 0x01)
-#define COM_MPMASTER(dev) (((dev)->id_flags >> 8) & 0x0ff)
-#define COM_NOTAST4(dev) ((dev)->id_flags & 0x04)
+#define COM_ISMULTIPORT(flags) ((flags) & 0x01)
+#define COM_MPMASTER(flags) (((flags) >> 8) & 0x0ff)
+#define COM_NOTAST4(flags) ((flags) & 0x04)
#endif /* COM_MULTIPORT */
-#define COM_CONSOLE(dev) ((dev)->id_flags & 0x10)
-#define COM_FORCECONSOLE(dev) ((dev)->id_flags & 0x20)
-#define COM_LLCONSOLE(dev) ((dev)->id_flags & 0x40)
-#define COM_LOSESOUTINTS(dev) ((dev)->id_flags & 0x08)
-#define COM_NOFIFO(dev) ((dev)->id_flags & 0x02)
-#define COM_ST16650A(dev) ((dev)->id_flags & 0x20000)
-#define COM_C_NOPROBE (0x40000)
-#define COM_NOPROBE(dev) ((dev)->id_flags & COM_C_NOPROBE)
-#define COM_C_IIR_TXRDYBUG (0x80000)
-#define COM_IIR_TXRDYBUG(dev) ((dev)->id_flags & COM_C_IIR_TXRDYBUG)
-#define COM_FIFOSIZE(dev) (((dev)->id_flags & 0xff000000) >> 24)
+#define COM_CONSOLE(flags) ((flags) & 0x10)
+#define COM_FORCECONSOLE(flags) ((flags) & 0x20)
+#define COM_LLCONSOLE(flags) ((flags) & 0x40)
+#define COM_LOSESOUTINTS(flags) ((flags) & 0x08)
+#define COM_NOFIFO(flags) ((flags) & 0x02)
+#define COM_ST16650A(flags) ((flags) & 0x20000)
+#define COM_C_NOPROBE (0x40000)
+#define COM_NOPROBE(flags) ((flags) & COM_C_NOPROBE)
+#define COM_C_IIR_TXRDYBUG (0x80000)
+#define COM_IIR_TXRDYBUG(flags) ((flags) & COM_C_IIR_TXRDYBUG)
+#define COM_FIFOSIZE(flags) (((flags) & 0xff000000) >> 24)
#ifdef PC98
#define com_emr com_msr /* Extension mode register for RSB-2000/3000 */
@@ -294,7 +309,7 @@ struct lbq {
/* com device structure */
struct com_s {
- u_int id_flags; /* Copy isa device falgas */
+ u_int flags; /* Copy isa device flags */
u_char state; /* miscellaneous flag bits */
bool_t active_out; /* nonzero if the callout device is open */
u_char cfcr_image; /* copy of value written to CFCR */
@@ -415,17 +430,18 @@ struct com_s {
static int espattach __P((struct isa_device *isdp, struct com_s *com,
Port_t esp_port));
#endif
-static int sioattach __P((struct isa_device *dev));
+static int sioattach __P((device_t dev));
+
static timeout_t siobusycheck;
static timeout_t siodtrwakeup;
static void comhardclose __P((struct com_s *com));
static void sioinput __P((struct com_s *com));
-static ointhand2_t siointr;
static void siointr1 __P((struct com_s *com));
+static void siointr __P((void *arg));
static int commctl __P((struct com_s *com, int bits, int how));
static int comparam __P((struct tty *tp, struct termios *t));
static swihand_t siopoll;
-static int sioprobe __P((struct isa_device *dev));
+static int sioprobe __P((device_t dev));
static void siosettimeout __P((void));
static int siosetwater __P((struct com_s *com, speed_t speed));
static void comstart __P((struct tty *tp));
@@ -437,11 +453,23 @@ static void disc_optim __P((struct tty *tp, struct termios *t,
static char driver_name[] = "sio";
/* table and macro for fast conversion from a unit number to its com struct */
-static struct com_s *p_com_addr[NSIOTOT];
-#define com_addr(unit) (p_com_addr[unit])
+static devclass_t sio_devclass;
+#define com_addr(unit) ((struct com_s *) \
+ devclass_get_softc(sio_devclass, unit))
+
+static device_method_t sio_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, sioprobe),
+ DEVMETHOD(device_attach, sioattach),
+
+ { 0, 0 }
+};
-struct isa_driver siodriver = {
- sioprobe, sioattach, driver_name
+static driver_t sio_driver = {
+ driver_name,
+ sio_methods,
+ DRIVER_TYPE_TTY,
+ sizeof(struct com_s),
};
static d_open_t sioopen;
@@ -461,10 +489,12 @@ static struct cdevsw sio_cdevsw = {
D_TTY,
};
-static int comconsole = -1;
+int comconsole = -1;
static volatile speed_t comdefaultrate = CONSPEED;
+static volatile speed_t gdbdefaultrate = CONSPEED;
static u_int com_events; /* input chars + weighted output completions */
static Port_t siocniobase;
+static Port_t siogdbiobase;
static bool_t sio_registered;
static int sio_timeout;
static int sio_timeouts_until_log;
@@ -518,7 +548,7 @@ static void pc98_i8251_set_cmd __P((struct com_s *com, int x));
static void pc98_i8251_or_cmd __P((struct com_s *com, int x));
static void pc98_i8251_clear_cmd __P((struct com_s *com, int x));
static void pc98_i8251_clear_or_cmd __P((struct com_s *com, int clr, int x));
-static int pc98_check_if_type __P((struct isa_device *dev, struct siodev *iod));
+static int pc98_check_if_type __P((device_t dev, struct siodev *iod));
static void pc98_check_sysclock __P((void));
static int pc98_set_ioport __P((struct com_s *com, int id_flags));
@@ -936,20 +966,24 @@ card_intr(struct pccard_devinfo *devi)
}
#endif /* NCARD > 0 */
+#define SET_FLAG(dev, bit) isa_set_flags(dev, isa_get_flags(dev) | (bit))
+#define CLR_FLAG(dev, bit) isa_set_flags(dev, isa_get_flags(dev) & ~(bit))
+
static int
sioprobe(dev)
- struct isa_device *dev;
+ device_t dev;
{
static bool_t already_init;
bool_t failures[10];
int fn;
- struct isa_device *idev;
+ device_t idev;
Port_t iobase;
intrmask_t irqmap[4];
intrmask_t irqs;
u_char mcr_image;
int result;
- struct isa_device *xdev;
+ device_t xdev;
+ u_int flags = isa_get_flags(dev);
#ifdef PC98
int irqout=0;
int ret = 0;
@@ -966,33 +1000,37 @@ sioprobe(dev)
* from any used port that shares the interrupt vector.
* XXX the gate enable is elsewhere for some multiports.
*/
- for (xdev = isa_devtab_tty; xdev->id_driver != NULL; xdev++)
+ device_t *devs;
+ int count, i;
+
+ devclass_get_devices(sio_devclass, &devs, &count);
#ifdef PC98
- if (xdev->id_driver == &siodriver && xdev->id_enabled) {
- tmp = (xdev->id_flags >> 24) & 0xff;
+ for (i = 0; i < count; i++) {
+ xdev = devs[i];
+ tmp = (flags >> 24) & 0xff;
if (IS_8251(tmp))
- outb((xdev->id_iobase & 0xff00) | PC98SIO_cmd_port(tmp & 0x0f), 0xf2);
+ outb((isa_get_port(xdev) & 0xff00) | PC98SIO_cmd_port(tmp & 0x0f), 0xf2);
else
if (tmp == COM_IF_RSA98III) {
- rsabase = xdev->id_iobase & 0xfff0;
-#if 0
- if (rsabase != xdev->id_iobase)
- return(0);
-#endif
- outb(xdev->id_iobase + 8 + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
+ rsabase = isa_get_port(xdev) & 0xfff0;
+ outb(isa_get_port(xdev) + 8 + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
} else
- outb(xdev->id_iobase + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
- }
+ outb(isa_get_port(xdev) + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
+ }
#else
- if (xdev->id_driver == &siodriver && xdev->id_enabled)
- outb(xdev->id_iobase + com_mcr, 0);
+ for (i = 0; i < count; i++) {
+ xdev = devs[i];
+ outb(isa_get_port(xdev) + com_mcr, 0);
+ }
#endif
+ free(devs, M_TEMP);
already_init = TRUE;
}
- if (COM_LLCONSOLE(dev)) {
- printf("sio%d: reserved for low-level i/o\n", dev->id_unit);
- return (0);
+ if (COM_LLCONSOLE(flags)) {
+ printf("sio%d: reserved for low-level i/o\n",
+ device_get_unit(dev));
+ return (ENXIO);
}
#ifdef PC98
@@ -1002,9 +1040,9 @@ sioprobe(dev)
* If the port is i8251 UART (internal, B98_01)
*/
if (pc98_check_if_type(dev, &iod) == -1)
- return 0;
+ return 0;
if (iod.irq > 0)
- dev->id_irq = 1 << iod.irq;
+ isa_set_irq(dev, iod.irq);
if (IS_8251(iod.if_type)) {
outb(iod.cmd, 0);
DELAY(10);
@@ -1055,8 +1093,8 @@ sioprobe(dev)
#ifdef PC98
if (iod.if_type == COM_IF_RSA98III) {
mcr_image = 0;
- rsabase = idev->id_iobase & 0xfff0;
- if (rsabase != idev->id_iobase)
+ rsabase = isa_get_port(idev) & 0xfff0;
+ if (rsabase != isa_get_port(idev))
return(0);
outb(rsabase + rsa_msr, 0x04);
outb(rsabase + rsa_frr, 0x00);
@@ -1069,51 +1107,50 @@ sioprobe(dev)
}
#endif /* PC98 */
#ifdef COM_MULTIPORT
- if (COM_ISMULTIPORT(dev)) {
- idev = find_isadev(isa_devtab_tty, &siodriver,
- COM_MPMASTER(dev));
+ if (COM_ISMULTIPORT(flags)) {
+ idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags));
if (idev == NULL) {
printf("sio%d: master device %d not configured\n",
- dev->id_unit, COM_MPMASTER(dev));
- dev->id_irq = 0;
+ device_get_unit(dev), COM_MPMASTER(flags));
+ isa_set_irq(dev, 0);
idev = dev;
}
#ifndef PC98
- if (!COM_NOTAST4(dev)) {
- outb(idev->id_iobase + com_scr,
- idev->id_irq ? 0x80 : 0);
+ if (!COM_NOTAST4(flags)) {
+ outb(isa_get_port(idev) + com_scr,
+ isa_get_irq(idev) >= 0 ? 0x80 : 0);
mcr_image = 0;
}
#endif /* !PC98 */
}
#endif /* COM_MULTIPORT */
- if (idev->id_irq == 0)
+ if (isa_get_irq(idev) < 0)
mcr_image = 0;
#ifdef PC98
tmp = if_16550a_type[iod.if_type & 0x0f].irr_write;
if (tmp != -1) {
/* MC16550II */
- switch (idev->id_irq) {
- case IRQ3: irqout = 4; break;
- case IRQ5: irqout = 5; break;
- case IRQ6: irqout = 6; break;
- case IRQ12: irqout = 7; break;
+ 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", dev->id_unit);
+ printf("sio%d: irq configuration error\n",
+ device_get_unit(dev));
return (0);
}
- outb((dev->id_iobase & 0x00ff) | tmp, irqout);
+ outb((isa_get_port(dev) & 0x00ff) | tmp, irqout);
}
port_shift = if_16550a_type[iod.if_type & 0x0f].port_shift;
#endif
bzero(failures, sizeof failures);
+ iobase = isa_get_port(dev);
#ifdef PC98
if (iod.if_type == COM_IF_RSA98III)
- iobase = dev->id_iobase + 8;
- else
+ iobase += 8;
#endif
- iobase = dev->id_iobase;
/*
* We don't want to get actual interrupts, just masked ones.
@@ -1190,9 +1227,8 @@ sioprobe(dev)
*/
#ifdef PC98
outb(iobase + (com_ier << port_shift), IER_ETXRDY);
- if (iod.if_type == COM_IF_RSA98III) {
+ if (iod.if_type == COM_IF_RSA98III)
outb(rsabase + rsa_ier, 0x04);
- }
#else
outb(iobase + com_ier, IER_ETXRDY);
#endif /* PC98 */
@@ -1228,7 +1264,7 @@ sioprobe(dev)
* It's a definitly Serial PCMCIA(16550A), but still be required
* for IIR_TXRDY implementation ( Palido 321s, DC-1S... )
*/
- if ( COM_NOPROBE(dev) ) {
+ if ( COM_NOPROBE(flags) ) {
/* Reading IIR register twice */
for ( fn = 0; fn < 2; fn ++ ) {
DELAY(10000);
@@ -1240,10 +1276,12 @@ sioprobe(dev)
}
/* Check IIR_TXRDY clear ? */
#ifdef PC98
- result = if_16550a_type[iod.if_type & 0x0f].io_size;
+ isa_set_portsize(dev,
+ if_16550a_type[iod.if_type & 0x0f].io_size);
#else
- result = IO_COMSIZE;
+ isa_set_portsize(dev, IO_COMSIZE);
#endif
+ result = 0;
if ( failures[6] & IIR_TXRDY ) {
/* Nop, Double check with clearing IER */
#ifdef PC98
@@ -1255,14 +1293,14 @@ sioprobe(dev)
if ( inb(iobase + com_iir) & IIR_NOPEND ) {
#endif
/* Ok. we're familia this gang */
- dev->id_flags |= COM_C_IIR_TXRDYBUG; /* Set IIR_TXRDYBUG */
+ SET_FLAG(dev, COM_C_IIR_TXRDYBUG); /* Set IIR_TXRDYBUG */
} else {
/* Unknow, Just omit this chip.. XXX*/
- result = 0;
+ result = ENXIO;
}
} else {
/* OK. this is well-known guys */
- dev->id_flags &= ~COM_C_IIR_TXRDYBUG; /*Clear IIR_TXRDYBUG*/
+ CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); /*Clear IIR_TXRDYBUG*/
}
#ifdef PC98
outb(iobase + (com_cfcr << port_shift), CFCR_8BITS);
@@ -1270,7 +1308,7 @@ sioprobe(dev)
outb(iobase + com_cfcr, CFCR_8BITS);
#endif
enable_intr();
- return (iobase == siocniobase ? IO_COMSIZE : result);
+ return (iobase == siocniobase ? 0 : result);
}
/*
@@ -1296,9 +1334,8 @@ sioprobe(dev)
#ifdef PC98
failures[4] = (inb(iobase + (com_iir << port_shift)) & IIR_IMASK)
- IIR_TXRDY;
- if (iod.if_type == COM_IF_RSA98III) {
+ if (iod.if_type == COM_IF_RSA98III)
inb(rsabase + rsa_srr);
- }
#else
failures[4] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_TXRDY;
#endif
@@ -1307,9 +1344,8 @@ sioprobe(dev)
#ifdef PC98
failures[6] = (inb(iobase + (com_iir << port_shift)) & IIR_IMASK)
- IIR_NOPEND;
- if (iod.if_type == COM_IF_RSA98III) {
+ if (iod.if_type == COM_IF_RSA98III)
inb(rsabase + rsa_srr);
- }
#else
failures[6] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
#endif
@@ -1319,7 +1355,7 @@ sioprobe(dev)
* 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.
+ * (unless there is another device driving at) 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.)
*/
@@ -1327,9 +1363,8 @@ sioprobe(dev)
outb(iobase + (com_ier << port_shift), 0);
outb(iobase + (com_cfcr << port_shift), CFCR_8BITS);
failures[7] = inb(iobase + (com_ier << port_shift));
- if (iod.if_type == COM_IF_RSA98III) {
+ if (iod.if_type == COM_IF_RSA98III)
outb(rsabase + rsa_ier, 0x00);
- }
#else
outb(iobase + com_ier, 0);
outb(iobase + com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */
@@ -1351,19 +1386,21 @@ sioprobe(dev)
enable_intr();
irqs = irqmap[1] & ~irqmap[0];
- if (idev->id_irq != 0 && (idev->id_irq & irqs) == 0)
+ if (isa_get_irq(idev) >= 0 && ((1 << isa_get_irq(idev)) & irqs) == 0)
printf(
"sio%d: configured irq %d not in bitmap of probed irqs %#x\n",
- dev->id_unit, ffs(idev->id_irq) - 1, irqs);
+ device_get_unit(dev), isa_get_irq(idev), irqs);
if (bootverbose)
printf("sio%d: irq maps: %#x %#x %#x %#x\n",
- dev->id_unit, irqmap[0], irqmap[1], irqmap[2], irqmap[3]);
+ device_get_unit(dev),
+ irqmap[0], irqmap[1], irqmap[2], irqmap[3]);
#ifdef PC98
- result = if_16550a_type[iod.if_type & 0x0f].io_size;
+ isa_set_portsize(dev, if_16550a_type[iod.if_type & 0x0f].io_size);
#else
- result = IO_COMSIZE;
+ isa_set_portsize(dev, IO_COMSIZE);
#endif
+ result = 0;
for (fn = 0; fn < sizeof failures; ++fn)
if (failures[fn]) {
#ifdef PC98
@@ -1371,10 +1408,10 @@ sioprobe(dev)
#else
outb(iobase + com_mcr, 0);
#endif
- result = 0;
+ result = ENXIO;
if (bootverbose) {
printf("sio%d: probe failed test(s):",
- dev->id_unit);
+ device_get_unit(dev));
for (fn = 0; fn < sizeof failures; ++fn)
if (failures[fn])
printf(" %d", fn);
@@ -1382,7 +1419,7 @@ sioprobe(dev)
}
break;
}
- return (iobase == siocniobase ? IO_COMSIZE : result);
+ return (iobase == siocniobase ? 0 : result);
}
#ifdef COM_ESP
@@ -1467,44 +1504,44 @@ espattach(isdp, com, esp_port)
#endif /* COM_ESP */
static int
-sioattach(isdp)
- struct isa_device *isdp;
+sioattach(dev)
+ device_t dev;
{
struct com_s *com;
- dev_t dev;
#ifdef COM_ESP
Port_t *espp;
#endif
-#ifdef COM_MULTIPORT
- struct isa_device *idev;
-#endif
Port_t iobase;
int s;
int unit;
+ void *ih;
+ struct resource *res;
+ int zero = 0;
+ u_int flags = isa_get_flags(dev);
#ifdef PC98
int port_shift = 0;
+ u_char *obuf;
u_long obufsize;
#endif
- isdp->id_ointr = siointr;
+#if 0
isdp->id_ri_flags |= RI_FAST;
+#endif
+ iobase = isa_get_port(dev);
#ifdef PC98
- if (((isdp->id_flags >> 24) & 0xff) == COM_IF_RSA98III)
- iobase = isdp->id_iobase + 8;
- else
+ if (((flags >> 24) & 0xff) == COM_IF_RSA98III)
+ iobase += 8;
#endif
- iobase = isdp->id_iobase;
- unit = isdp->id_unit;
-#ifndef PC98
- com = malloc(sizeof *com, M_DEVBUF, M_NOWAIT);
-#else
+ unit = device_get_unit(dev);
+ com = device_get_softc(dev);
+#ifdef PC98
obufsize = 256;
- if (((isdp->id_flags >> 24) & 0xff) == COM_IF_RSA98III)
+ if (((flags >> 24) & 0xff) == COM_IF_RSA98III)
obufsize = 2048;
- com = malloc((sizeof *com) + obufsize * 2, M_DEVBUF, M_NOWAIT);
-#endif
- if (com == NULL)
+ if ((obuf = malloc(obufsize * 2, M_DEVBUF, M_NOWAIT)) == NULL)
return (0);
+ bzero(obuf, obufsize * 2);
+#endif
/*
* sioprobe() has initialized the device registers as follows:
@@ -1521,23 +1558,22 @@ sioattach(isdp)
bzero(com, sizeof *com);
#ifdef PC98
com->obufsize = obufsize;
- com->obuf1 = (u_char *)com + (sizeof *com);
- com->obuf2 = com->obuf1 + obufsize;
- bzero(com->obuf1, obufsize * 2);
+ com->obuf1 = obuf;
+ com->obuf2 = obuf + obufsize;
#endif
com->unit = unit;
com->cfcr_image = CFCR_8BITS;
com->dtr_wait = 3 * hz;
- com->loses_outints = COM_LOSESOUTINTS(isdp) != 0;
- com->no_irq = isdp->id_irq == 0;
+ com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
+ com->no_irq = isa_get_irq(dev) < 0;
com->tx_fifo_size = 1;
com->obufs[0].l_head = com->obuf1;
com->obufs[1].l_head = com->obuf2;
com->iobase = iobase;
#ifdef PC98
- if (pc98_set_ioport(com, isdp->id_flags) == -1) {
- com->pc98_if_type = (isdp->id_flags >> 24) & 0xff;
+ if (pc98_set_ioport(com, isa_get_flags(dev)) == -1) {
+ com->pc98_if_type = (isa_get_flags(dev) >> 24) & 0xff;
port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift;
com->data_port = iobase + (com_data << port_shift);
com->int_id_port = iobase + (com_iir << port_shift);
@@ -1597,9 +1633,9 @@ sioattach(isdp)
#ifndef PC98
#ifdef COM_MULTIPORT
- if (!COM_ISMULTIPORT(isdp) && !COM_IIR_TXRDYBUG(isdp))
+ if (!COM_ISMULTIPORT(flags) && !COM_IIR_TXRDYBUG(flags))
#else
- if (!COM_IIR_TXRDYBUG(isdp))
+ if (!COM_IIR_TXRDYBUG(flags))
#endif
{
u_char scr;
@@ -1643,7 +1679,7 @@ sioattach(isdp)
printf(" 16550?");
break;
case FIFO_RX_HIGH:
- if (COM_NOFIFO(isdp)) {
+ if (COM_NOFIFO(flags)) {
printf(" 16550A fifo disabled");
} else {
com->hasfifo = TRUE;
@@ -1651,12 +1687,12 @@ sioattach(isdp)
com->tx_fifo_size = 0; /* XXX flag conflicts. */
printf(" 16550A");
#else
- if (COM_ST16650A(isdp)) {
+ if (COM_ST16650A(flags)) {
com->st16650a = 1;
com->tx_fifo_size = 32;
printf(" ST16650A");
} else {
- com->tx_fifo_size = COM_FIFOSIZE(isdp);
+ com->tx_fifo_size = COM_FIFOSIZE(flags);
printf(" 16550A");
}
#endif
@@ -1664,7 +1700,7 @@ sioattach(isdp)
#ifdef PC98
if (com->pc98_if_type == COM_IF_RSA98III) {
com->tx_fifo_size = 2048;
- com->rsabase = isdp->id_iobase;
+ com->rsabase = isa_get_port(dev);
outb(com->rsabase + rsa_ier, 0x00);
outb(com->rsabase + rsa_frr, 0x00);
}
@@ -1675,7 +1711,7 @@ sioattach(isdp)
if (com->pc98_if_type == COM_IF_ESP98)
#endif
for (espp = likely_esp_ports; *espp != 0; espp++)
- if (espattach(isdp, com, *espp)) {
+ if (espattach(dev, com, *espp)) {
com->tx_fifo_size = 1024;
break;
}
@@ -1761,15 +1797,15 @@ determined_type: ;
#endif
#ifdef COM_MULTIPORT
- if (COM_ISMULTIPORT(isdp)) {
+ if (COM_ISMULTIPORT(flags)) {
com->multiport = TRUE;
printf(" (multiport");
- if (unit == COM_MPMASTER(isdp))
+ if (unit == COM_MPMASTER(flags))
printf(" master");
printf(")");
- idev = find_isadev(isa_devtab_tty, &siodriver,
- COM_MPMASTER(isdp));
- com->no_irq = (idev == NULL || idev->id_irq == 0);
+ com->no_irq =
+ isa_get_irq(devclass_get_device
+ (sio_devclass, COM_MPMASTER(flags))) < 0;
}
#endif /* COM_MULTIPORT */
#ifdef PC98
@@ -1777,17 +1813,11 @@ determined_type: ;
#endif
if (unit == comconsole)
printf(", console");
- if ( COM_IIR_TXRDYBUG(isdp) )
+ if ( COM_IIR_TXRDYBUG(flags) )
printf(" with a bogus IIR_TXRDY register");
printf("\n");
- s = spltty();
- com_addr(unit) = com;
- splx(s);
-
if (!sio_registered) {
- dev = makedev(CDEV_MAJOR, 0);
- cdevsw_add(&dev, &sio_cdevsw, NULL);
register_swi(SWI_TTY, siopoll);
sio_registered = TRUE;
}
@@ -1811,10 +1841,16 @@ determined_type: ;
unit | CALLOUT_MASK | CONTROL_LOCK_STATE, DV_CHR,
UID_UUCP, GID_DIALER, 0660, "cuala%r", unit);
#endif
- com->id_flags = isdp->id_flags; /* Heritate id_flags for later */
+ com->flags = isa_get_flags(dev); /* Heritate id_flags for later */
com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
pps_init(&com->pps);
- return (1);
+
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, 0ul, ~0ul, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ BUS_SETUP_INTR(device_get_parent(dev), dev, res, siointr, com,
+ &ih);
+
+ return (0);
}
static int
@@ -1995,7 +2031,7 @@ open_top:
(void) inb(com->data_port);
com->prev_modem_status = com->last_modem_status
= inb(com->modem_status_port);
- if (COM_IIR_TXRDYBUG(com)) {
+ if (COM_IIR_TXRDYBUG(com->flags)) {
outb(com->intr_ctl_port, IER_ERXRDY | IER_ERLS
| IER_EMSC);
} else {
@@ -2093,10 +2129,9 @@ sioclose(dev, flag, mode, p)
if (com->gone) {
printf("sio%d: gone\n", com->unit);
s = spltty();
- com_addr(com->unit) = NULL;
if (com->ibuf != NULL)
free(com->ibuf, M_DEVBUF);
- bzero(tp, sizeof *tp);
+ bzero(tp,sizeof *tp);
free(com, M_DEVBUF);
splx(s);
}
@@ -2402,16 +2437,15 @@ sioinput(com)
#endif
}
-static void
-siointr(unit)
- int unit;
+void
+siointr(arg)
+ void *arg;
{
#ifndef COM_MULTIPORT
COM_LOCK();
- siointr1(com_addr(unit));
+ siointr1((struct com_s *) arg);
COM_UNLOCK();
#else /* COM_MULTIPORT */
- struct com_s *com;
bool_t possibly_more_intrs;
#ifdef PC98
u_char rsa_buf_status;
@@ -2714,7 +2748,7 @@ cont:
com_int_Tx_enable(com);
#endif
com->obufq.l_head = ioptr;
- if (COM_IIR_TXRDYBUG(com)) {
+ if (COM_IIR_TXRDYBUG(com->flags)) {
int_ctl_new = int_ctl | IER_ETXRDY;
}
if (ioptr >= com->obufq.l_tail) {
@@ -2729,7 +2763,7 @@ cont:
com->obufq.l_next = qp;
} else {
/* output just completed */
- if ( COM_IIR_TXRDYBUG(com) ) {
+ if ( COM_IIR_TXRDYBUG(com->flags) ) {
int_ctl_new = int_ctl & ~IER_ETXRDY;
}
com->state &= ~CS_BUSY;
@@ -2745,7 +2779,7 @@ cont:
setsofttty(); /* handle at high level ASAP */
}
}
- if ( COM_IIR_TXRDYBUG(com) && (int_ctl != int_ctl_new)) {
+ if ( COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) {
#ifdef PC98
if (com->pc98_if_type == COM_IF_RSA98III) {
int_ctl_new &= ~(IER_ETXRDY | IER_ERXRDY);
@@ -2794,7 +2828,7 @@ sioioctl(dev, cmd, data, flag, p)
int s;
struct tty *tp;
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
- int oldcmd;
+ u_long oldcmd;
struct termios term;
#endif
@@ -3872,10 +3906,11 @@ struct siocnstate {
};
static speed_t siocngetspeed __P((Port_t, struct speedtab *));
-static void siocnclose __P((struct siocnstate *sp));
-static void siocnopen __P((struct siocnstate *sp));
-static void siocntxwait __P((void));
+static void siocnclose __P((struct siocnstate *sp, Port_t iobase));
+static void siocnopen __P((struct siocnstate *sp, Port_t iobase, int speed));
+static void siocntxwait __P((Port_t iobase));
+#ifdef __i386__
/*
* XXX: sciocnget() and sciocnputc() are not declared static, as they are
* referred to from i386/i386/i386-gdbstub.c.
@@ -3888,8 +3923,11 @@ static cn_checkc_t siocncheckc;
CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
+#endif
+
static void
-siocntxwait()
+siocntxwait(iobase)
+ Port_t iobase;
{
int timo;
@@ -3899,7 +3937,7 @@ siocntxwait()
* transmits.
*/
timo = 100000;
- while ((inb(siocniobase + com_lsr) & (LSR_TSRE | LSR_TXRDY))
+ while ((inb(iobase + com_lsr) & (LSR_TSRE | LSR_TXRDY))
!= (LSR_TSRE | LSR_TXRDY) && --timo != 0)
;
}
@@ -3941,23 +3979,23 @@ siocngetspeed(iobase, table)
}
static void
-siocnopen(sp)
+siocnopen(sp, iobase, speed)
struct siocnstate *sp;
+ Port_t iobase;
+ int speed;
{
int divisor;
u_char dlbh;
u_char dlbl;
- Port_t iobase;
/*
* 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.
*/
- iobase = siocniobase;
sp->ier = inb(iobase + com_ier);
outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */
- siocntxwait();
+ siocntxwait(iobase);
sp->cfcr = inb(iobase + com_cfcr);
outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
sp->dlbl = inb(iobase + com_dlbl);
@@ -3968,7 +4006,7 @@ siocnopen(sp)
* data input register. This also reduces the effects of the
* UMC8669F bug.
*/
- divisor = ttspeedtab(comdefaultrate, comspeedtab);
+ divisor = ttspeedtab(speed, comspeedtab);
dlbl = divisor & 0xFF;
if (sp->dlbl != dlbl)
outb(iobase + com_dlbl, dlbl);
@@ -3986,16 +4024,14 @@ siocnopen(sp)
}
static void
-siocnclose(sp)
+siocnclose(sp, iobase)
struct siocnstate *sp;
+ Port_t iobase;
{
- Port_t iobase;
-
/*
* Restore the device control registers.
*/
- siocntxwait();
- iobase = siocniobase;
+ siocntxwait(iobase);
outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
if (sp->dlbl != inb(iobase + com_dlbl))
outb(iobase + com_dlbl, sp->dlbl);
@@ -4009,14 +4045,16 @@ siocnclose(sp)
outb(iobase + com_ier, sp->ier);
}
-static void
+#ifdef __i386__
+static
+#endif
+void
siocnprobe(cp)
struct consdev *cp;
{
speed_t boot_speed;
u_char cfcr;
- struct isa_device *dvp;
- int s;
+ int s, unit;
struct siocnstate sp;
/*
@@ -4034,10 +4072,16 @@ siocnprobe(cp)
* don't need to probe.
*/
cp->cn_pri = CN_DEAD;
- for (dvp = isa_devtab_tty; dvp->id_driver != NULL; dvp++)
- if (dvp->id_driver == &siodriver && dvp->id_enabled
- && COM_CONSOLE(dvp)) {
- siocniobase = dvp->id_iobase;
+
+ for (unit = 0; unit < 16; unit++) { /* XXX need to know how many */
+ int flags;
+ if (resource_int_value("sio", unit, "flags", &flags))
+ continue;
+ if (COM_CONSOLE(flags)) {
+ int port;
+ if (resource_int_value("sio", unit, "port", &port))
+ continue;
+ siocniobase = port;
s = spltty();
if (boothowto & RB_SERIAL) {
boot_speed = siocngetspeed(siocniobase,
@@ -4063,26 +4107,119 @@ siocnprobe(cp)
(u_int) COMBRD(comdefaultrate) >> 8);
outb(siocniobase + com_cfcr, cfcr);
- siocnopen(&sp);
+ siocnopen(&sp, siocniobase, comdefaultrate);
splx(s);
- if (!COM_LLCONSOLE(dvp)) {
- cp->cn_dev = makedev(CDEV_MAJOR, dvp->id_unit);
- cp->cn_pri = COM_FORCECONSOLE(dvp)
+ if (!COM_LLCONSOLE(flags)) {
+ cp->cn_dev = makedev(CDEV_MAJOR, unit);
+ cp->cn_pri = COM_FORCECONSOLE(flags)
|| boothowto & RB_SERIAL
? CN_REMOTE : CN_NORMAL;
}
break;
}
+ }
}
-static void
+#ifdef __alpha__
+
+struct consdev siocons = {
+ NULL, NULL, siocngetc, siocncheckc, siocnputc,
+ NULL, makedev(CDEV_MAJOR, 0), CN_NORMAL,
+};
+
+extern struct consdev *cn_tab;
+
+int
+siocnattach(port, speed)
+ int port;
+ int speed;
+{
+ int s;
+ u_char cfcr;
+ struct siocnstate sp;
+
+ siocniobase = port;
+ comdefaultrate = speed;
+
+ s = spltty();
+
+ /*
+ * 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(siocniobase + com_cfcr);
+ outb(siocniobase + com_cfcr, CFCR_DLAB | cfcr);
+ outb(siocniobase + com_dlbl,
+ COMBRD(comdefaultrate) & 0xff);
+ outb(siocniobase + com_dlbh,
+ (u_int) COMBRD(comdefaultrate) >> 8);
+ outb(siocniobase + com_cfcr, cfcr);
+
+ siocnopen(&sp, siocniobase, comdefaultrate);
+ splx(s);
+
+ cn_tab = &siocons;
+ return 0;
+}
+
+int
+siogdbattach(port, speed)
+ int port;
+ int speed;
+{
+ int s;
+ u_char cfcr;
+ struct siocnstate sp;
+
+ siogdbiobase = port;
+ gdbdefaultrate = speed;
+
+ s = spltty();
+
+ /*
+ * 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(siogdbiobase + com_cfcr);
+ outb(siogdbiobase + com_cfcr, CFCR_DLAB | cfcr);
+ outb(siogdbiobase + com_dlbl,
+ COMBRD(gdbdefaultrate) & 0xff);
+ outb(siogdbiobase + com_dlbh,
+ (u_int) COMBRD(gdbdefaultrate) >> 8);
+ outb(siogdbiobase + com_cfcr, cfcr);
+
+ siocnopen(&sp, siogdbiobase, gdbdefaultrate);
+ splx(s);
+
+ return 0;
+}
+
+#endif
+
+#ifdef __i386__
+static
+#endif
+void
siocninit(cp)
struct consdev *cp;
{
comconsole = DEV_TO_UNIT(cp->cn_dev);
}
-static int
+#ifdef __i386__
+static
+#endif
+int
siocncheckc(dev)
dev_t dev;
{
@@ -4093,12 +4230,12 @@ siocncheckc(dev)
iobase = siocniobase;
s = spltty();
- siocnopen(&sp);
+ siocnopen(&sp, iobase, comdefaultrate);
if (inb(iobase + com_lsr) & LSR_RXRDY)
c = inb(iobase + com_data);
else
c = -1;
- siocnclose(&sp);
+ siocnclose(&sp, iobase);
splx(s);
return (c);
}
@@ -4115,11 +4252,11 @@ siocngetc(dev)
iobase = siocniobase;
s = spltty();
- siocnopen(&sp);
+ siocnopen(&sp, iobase, comdefaultrate);
while (!(inb(iobase + com_lsr) & LSR_RXRDY))
;
c = inb(iobase + com_data);
- siocnclose(&sp);
+ siocnclose(&sp, iobase);
splx(s);
return (c);
}
@@ -4133,10 +4270,44 @@ siocnputc(dev, c)
struct siocnstate sp;
s = spltty();
- siocnopen(&sp);
- siocntxwait();
+ siocnopen(&sp, siocniobase, comdefaultrate);
+ siocntxwait(siocniobase);
outb(siocniobase + com_data, c);
- siocnclose(&sp);
+ siocnclose(&sp, siocniobase);
+ splx(s);
+}
+
+int
+siogdbgetc()
+{
+ int c;
+ Port_t iobase;
+ int s;
+ struct siocnstate sp;
+
+ iobase = siogdbiobase;
+ s = spltty();
+ siocnopen(&sp, iobase, gdbdefaultrate);
+ while (!(inb(iobase + com_lsr) & LSR_RXRDY))
+ ;
+ c = inb(iobase + com_data);
+ siocnclose(&sp, iobase);
+ splx(s);
+ return (c);
+}
+
+void
+siogdbputc(c)
+ int c;
+{
+ int s;
+ struct siocnstate sp;
+
+ s = spltty();
+ siocnopen(&sp, siogdbiobase, gdbdefaultrate);
+ siocntxwait(siogdbiobase);
+ outb(siogdbiobase + com_data, c);
+ siocnclose(&sp, siogdbiobase);
splx(s);
}
@@ -4204,7 +4375,6 @@ static void
siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
{
struct pnp_cinfo d;
- struct isa_device *dvp;
if (dev->id_unit >= NSIOTOT)
return;
@@ -4226,9 +4396,7 @@ siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
if (dev->id_driver == NULL) {
dev->id_driver = &siodriver;
- dvp = find_isadev(isa_devtab_tty, &siodriver, 0);
- if (dvp != NULL)
- dev->id_id = dvp->id_id;
+ dev->id_id = isa_compat_nextid();
}
if ((dev->id_alive = sioprobe(dev)) != 0)
@@ -4238,6 +4406,9 @@ siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
}
#endif
+CDEV_DRIVER_MODULE(sio, isa, sio_driver, sio_devclass,
+ CDEV_MAJOR, sio_cdevsw, 0, 0);
+
#ifdef PC98
/*
* pc98 local function
@@ -4698,7 +4869,7 @@ pc98_set_baud_rate( struct com_s *com, int count )
}
}
static int
-pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
+pc98_check_if_type(device_t dev, struct siodev *iod)
{
int irr, io, if_type, tmp;
static short irq_tab[2][8] = {
@@ -4706,13 +4877,13 @@ pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
{ 3, 10, 12, 13, 5, 6, 9, -1}
};
- iod->if_type = if_type = (dev->id_flags >> 24) & 0xff;
+ iod->if_type = if_type = (isa_get_flags(dev) >> 24) & 0xff;
if ((if_type < 0 || if_type > COM_IF_END1) &&
(if_type < 0x10 || if_type > COM_IF_END2))
return(-1);
if_type &= 0x0f;
iod->irq = 0;
- io = dev->id_iobase & 0xff00;
+ io = isa_get_port(dev) & 0xff00;
if (IS_8251(iod->if_type)) {
if (PC98SIO_func_port(if_type) != -1) {
@@ -4744,7 +4915,7 @@ pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
}
} else {
tmp = inb( iod->mod ) & if_8251_type[if_type].irr_mask;
- if ((dev->id_iobase & 0xff) == IO_COM2)
+ if ((isa_get_port(dev) & 0xff) == IO_COM2)
iod->irq = irq_tab[0][tmp];
else
iod->irq = irq_tab[1][tmp];
@@ -4756,7 +4927,7 @@ pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
#endif
if (irr != -1) {
tmp = inb(io | irr);
- if (dev->id_iobase & 0x01) /* XXX depend on RSB-384 */
+ 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];
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC
index 1bde433..2398f2f 100644
--- a/sys/pc98/conf/GENERIC
+++ b/sys/pc98/conf/GENERIC
@@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
-# $Id: GENERIC98,v 1.69 1999/03/17 08:56:28 kato Exp $
+# $Id: GENERIC98,v 1.70 1999/04/01 13:39:27 kato Exp $
# GENERIC98 -- Generic PC98 machine with WD/SCSI disks
@@ -23,6 +23,8 @@ cpu "I686_CPU"
ident "GENERIC98"
maxusers 32
+#makeoptions DEBUG="-g" #Build kernel with gdb(1) debug symbols
+
options "PC98" #PC98
options MATH_EMULATE #Support for x87 emulation
options INET #InterNETworking
@@ -46,10 +48,6 @@ options FAILSAFE #Be conservative
options USERCONFIG #boot -c editor
options VISUAL_USERCONFIG #visual boot -c editor
-options SYSVSHM
-options SYSVSEM
-options SYSVMSG
-
options COM_MULTIPORT
#
@@ -67,9 +65,9 @@ config kernel root on wd0
#options NAPIC=1 # number of IO APICs
#options NINTR=24 # number of INTs
-controller isa0
-controller pnp0 # PnP support for ISA
-controller pci0
+controller isa0 at nexus?
+#controller pnp0 # PnP support for ISA
+controller pci0 at nexus?
controller fdc0 at isa? port "IO_FD1" bio irq 11 drq 2
disk fd0 at fdc0 drive 0
@@ -84,9 +82,8 @@ disk wd0 at wdc0 drive 0
#disk wd2 at wdc0 drive 2
#disk wd3 at wdc0 drive 3
-options ATAPI #Enable ATAPI support for IDE bus
-options ATAPI_STATIC #Don't do it as an LKM
device wcd0 #IDE CD-ROM
+#device wfd0 #IDE Floppy (e.g. LS-120)
# A single entry for any of these controllers (ncr, ahb, ahc) is
# sufficient for any number of installed devices.
@@ -132,16 +129,17 @@ device pckbd0 at isa? port IO_KBD tty irq 1
device gdc0 at isa?
-#pseudo-device splash
+# splash screen/screen saver
+pseudo-device splash
device sc0 at isa? tty
-device npx0 at isa? port IO_NPX irq 8
+device npx0 at nexus? port IO_NPX irq 8
#
# Laptop support (see LINT for more options)
#
-device apm0 at isa? disable flags 0x31 # Advanced Power Management
+device apm0 at nexus? disable flags 0x31 # Advanced Power Management
# PCCARD (PCMCIA) support
#controller card0
@@ -179,22 +177,21 @@ device sio1 at isa? port 0x238 tty irq 5 flags 0x12000000
#device lpt0 at isa? port IO_LPT tty
device mse0 at isa? port IO_MSE tty irq 13
-# Order is important here due to intrusive probes, do *not* alphabetize
-# this list of network interfaces until the probes have been fixed.
-# Right now it appears that the ie0 must be probed before ep0. See
-# revision 1.20 of this file.
-device ax0
-device de0
-device fxp0
-device mx0
-device pn0
-device rl0
-device tl0
-device tx0
-device vr0
-device vx0
-device wb0
-device xl0
+#
+# The following Ethernet NICs are all PCI devices.
+#
+device ax0 # ASIX AX88140A
+device de0 # DEC/Intel DC21x4x (``Tulip'')
+device fxp0 # Intel EtherExpress PRO/100B (82557, 82558)
+device mx0 # Macronix 98713/98715/98725 (``PMAC'')
+device pn0 # Lite-On 82c168/82c169 (``PNIC'')
+device rl0 # RealTek 8129/8139
+device tl0 # Texas Instruments ThunderLAN
+device tx0 # SMC 9432TX (83c170 ``EPIC'')
+device vr0 # VIA Rhine, Rhine II
+device vx0 # 3Com 3c590, 3c595 (``Vortex'')
+device wb0 # Winbond W89C840F
+device xl0 # 3Com 3c90x (``Boomerang'', ``Cyclone'')
#
# DP8390 NIC
@@ -228,7 +225,7 @@ device ep0 at isa? port 0x40d0 net irq 3
device fe0 at isa? port 0x00d0 net irq 3
device fe1 at isa? port 0x73d0 net irq 5
device lnc0 at isa? port 0x03d0 net irq 6
-device zp0 at isa? port 0x00d0 net irq 10 iomem 0xe0000
+#device zp0 at isa? port 0x00d0 net irq 10 iomem 0xe0000
options "FE_8BIT_SUPPORT" # LAC-98 support
@@ -253,6 +250,13 @@ pseudo-device gzip # Exec gzipped a.out's
# the costs of each syscall.
options KTRACE #kernel tracing
+# This provides support for System V shared memory and message queues.
+#
+options SYSVSHM
+options SYSVMSG
+options SYSVSEM
+
+
# The `bpfilter' pseudo-device enables the Berkeley Packet Filter. Be
# aware of the legal and administrative consequences of enabling this
# option. The number of devices determines the maximum number of
diff --git a/sys/pc98/conf/GENERIC98 b/sys/pc98/conf/GENERIC98
index 1bde433..2398f2f 100644
--- a/sys/pc98/conf/GENERIC98
+++ b/sys/pc98/conf/GENERIC98
@@ -11,7 +11,7 @@
# device lines is present in the ./LINT configuration file. If you are
# in doubt as to the purpose or necessity of a line, check first in LINT.
#
-# $Id: GENERIC98,v 1.69 1999/03/17 08:56:28 kato Exp $
+# $Id: GENERIC98,v 1.70 1999/04/01 13:39:27 kato Exp $
# GENERIC98 -- Generic PC98 machine with WD/SCSI disks
@@ -23,6 +23,8 @@ cpu "I686_CPU"
ident "GENERIC98"
maxusers 32
+#makeoptions DEBUG="-g" #Build kernel with gdb(1) debug symbols
+
options "PC98" #PC98
options MATH_EMULATE #Support for x87 emulation
options INET #InterNETworking
@@ -46,10 +48,6 @@ options FAILSAFE #Be conservative
options USERCONFIG #boot -c editor
options VISUAL_USERCONFIG #visual boot -c editor
-options SYSVSHM
-options SYSVSEM
-options SYSVMSG
-
options COM_MULTIPORT
#
@@ -67,9 +65,9 @@ config kernel root on wd0
#options NAPIC=1 # number of IO APICs
#options NINTR=24 # number of INTs
-controller isa0
-controller pnp0 # PnP support for ISA
-controller pci0
+controller isa0 at nexus?
+#controller pnp0 # PnP support for ISA
+controller pci0 at nexus?
controller fdc0 at isa? port "IO_FD1" bio irq 11 drq 2
disk fd0 at fdc0 drive 0
@@ -84,9 +82,8 @@ disk wd0 at wdc0 drive 0
#disk wd2 at wdc0 drive 2
#disk wd3 at wdc0 drive 3
-options ATAPI #Enable ATAPI support for IDE bus
-options ATAPI_STATIC #Don't do it as an LKM
device wcd0 #IDE CD-ROM
+#device wfd0 #IDE Floppy (e.g. LS-120)
# A single entry for any of these controllers (ncr, ahb, ahc) is
# sufficient for any number of installed devices.
@@ -132,16 +129,17 @@ device pckbd0 at isa? port IO_KBD tty irq 1
device gdc0 at isa?
-#pseudo-device splash
+# splash screen/screen saver
+pseudo-device splash
device sc0 at isa? tty
-device npx0 at isa? port IO_NPX irq 8
+device npx0 at nexus? port IO_NPX irq 8
#
# Laptop support (see LINT for more options)
#
-device apm0 at isa? disable flags 0x31 # Advanced Power Management
+device apm0 at nexus? disable flags 0x31 # Advanced Power Management
# PCCARD (PCMCIA) support
#controller card0
@@ -179,22 +177,21 @@ device sio1 at isa? port 0x238 tty irq 5 flags 0x12000000
#device lpt0 at isa? port IO_LPT tty
device mse0 at isa? port IO_MSE tty irq 13
-# Order is important here due to intrusive probes, do *not* alphabetize
-# this list of network interfaces until the probes have been fixed.
-# Right now it appears that the ie0 must be probed before ep0. See
-# revision 1.20 of this file.
-device ax0
-device de0
-device fxp0
-device mx0
-device pn0
-device rl0
-device tl0
-device tx0
-device vr0
-device vx0
-device wb0
-device xl0
+#
+# The following Ethernet NICs are all PCI devices.
+#
+device ax0 # ASIX AX88140A
+device de0 # DEC/Intel DC21x4x (``Tulip'')
+device fxp0 # Intel EtherExpress PRO/100B (82557, 82558)
+device mx0 # Macronix 98713/98715/98725 (``PMAC'')
+device pn0 # Lite-On 82c168/82c169 (``PNIC'')
+device rl0 # RealTek 8129/8139
+device tl0 # Texas Instruments ThunderLAN
+device tx0 # SMC 9432TX (83c170 ``EPIC'')
+device vr0 # VIA Rhine, Rhine II
+device vx0 # 3Com 3c590, 3c595 (``Vortex'')
+device wb0 # Winbond W89C840F
+device xl0 # 3Com 3c90x (``Boomerang'', ``Cyclone'')
#
# DP8390 NIC
@@ -228,7 +225,7 @@ device ep0 at isa? port 0x40d0 net irq 3
device fe0 at isa? port 0x00d0 net irq 3
device fe1 at isa? port 0x73d0 net irq 5
device lnc0 at isa? port 0x03d0 net irq 6
-device zp0 at isa? port 0x00d0 net irq 10 iomem 0xe0000
+#device zp0 at isa? port 0x00d0 net irq 10 iomem 0xe0000
options "FE_8BIT_SUPPORT" # LAC-98 support
@@ -253,6 +250,13 @@ pseudo-device gzip # Exec gzipped a.out's
# the costs of each syscall.
options KTRACE #kernel tracing
+# This provides support for System V shared memory and message queues.
+#
+options SYSVSHM
+options SYSVMSG
+options SYSVSEM
+
+
# The `bpfilter' pseudo-device enables the Berkeley Packet Filter. Be
# aware of the legal and administrative consequences of enabling this
# option. The number of devices determines the maximum number of
diff --git a/sys/pc98/conf/Makefile.pc98 b/sys/pc98/conf/Makefile.pc98
index f9c6717..78ffe97 100644
--- a/sys/pc98/conf/Makefile.pc98
+++ b/sys/pc98/conf/Makefile.pc98
@@ -3,7 +3,7 @@
# Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.pc98,v 1.58 1999/04/07 09:28:03 grog Exp $
+# $Id: Makefile.pc98,v 1.59 1999/04/11 03:40:11 grog Exp $
#
# Makefile for FreeBSD
#
@@ -19,7 +19,7 @@
#
# Which version of config(8) is required.
-%VERSREQ= 300010
+%VERSREQ= 400013
KERNFORMAT?= elf
@@ -89,6 +89,7 @@ SYSTEM_DEP= Makefile symbols.exclude symbols.sort ${SYSTEM_OBJS}
SYMORDER_EXCLUDE=-x symbols.exclude
.endif
SYSTEM_LD_HEAD= @echo loading ${.TARGET}; rm -f ${.TARGET}
+
.if ${KERNFORMAT} == aout || ${KERNFORMAT} == aoutkld
SYSTEM_OBJS= locore.o vnode_if.o ${OBJS} ioconf.o param.o config.o
SYSTEM_LD= @${LD} -aout -Bforcedynamic -Z -T ${LOAD_ADDRESS} -o ${.TARGET} -X ${SYSTEM_OBJS} vers.o
@@ -96,6 +97,7 @@ SYSTEM_LD_TAIL= @echo rearranging symbols; \
symorder -m ${SYMORDER_EXCLUDE} symbols.sort ${.TARGET}; \
size -aout ${.TARGET} ; chmod 755 ${.TARGET}
.endif
+
.if ${KERNFORMAT} == elf
SYSTEM_OBJS= locore.o setdef0.o vnode_if.o ${OBJS} ioconf.o param.o config.o \
setdef1.o hack.So
@@ -106,6 +108,12 @@ SYSTEM_LD_TAIL= @size -elf ${.TARGET} ; chmod 755 ${.TARGET}
SYSTEM_DEP+= $S/i386/conf/kernel.script
.endif
+.if defined(DEBUG)
+FULLKERNEL= ${KERNEL}.debug
+.else
+FULLKERNEL= ${KERNEL}
+.endif
+
%BEFORE_DEPEND
%OBJS
@@ -209,47 +217,20 @@ tags:
@echo "see $S/kern/Makefile for tags"
.if defined(DEBUG)
-install: ${KERNEL}
-.if ${KERNFORMAT} == "elf" && !defined(FORCE)
- @if [ -f /${KERNEL} -a "`file /${KERNEL} 2>/dev/null | grep ELF`" = "" ]; then \
- echo "WARNING: You are about to install an ELF kernel for the first time!" ; \
- echo "Please be sure you have upgraded your bootblocks and/or /boot/loader so" ; \
- echo "that you can boot it. Old bootblocks WILL NOT WORK! Please read:" ; \
- echo "http://www.freebsd.org/~peter/elfday.html for information." ; \
- echo "If you are satisfied you can boot an ELF kernel, type: make -DFORCE install" ; \
- exit 1 ; \
- fi
-.endif
-.if exists(${DESTDIR}/${KERNEL})
- -chflags noschg ${DESTDIR}/${KERNEL}
- mv ${DESTDIR}/${KERNEL} ${DESTDIR}/${KERNEL}.old
+${KERNEL}: ${FULLKERNEL}
+.if ${KERNFORMAT} == "elf"
+ objcopy --strip-debug ${FULLKERNEL} ${KERNEL}
+.else
+ cp ${FULLKERNEL} ${KERNEL}
+ strip -d kernel
.endif
- PATH=$${PATH}:/sbin:/usr/sbin; \
- if [ `sysctl -n kern.bootfile` = ${DESTDIR}/${KERNEL} ] ; then \
- sysctl -w kern.bootfile=${DESTDIR}/${KERNEL}.old ; \
- if [ -f /var/db/kvm_kernel.db ] ; then \
- mv -f /var/db/kvm_kernel.db /var/db/kvm_kernel.old.db ; \
- fi \
- fi
- install -c -m 555 -o root -g wheel -fschg ${KERNEL} ${DESTDIR}/
-
.endif
-${INSTALL}:
- @if [ ! -f ${KERNEL} ] ; then \
- echo "You must first build your kernel before trying to install." ; \
+install install.debug:
+ @if [ ! -f ${KERNEL}${.TARGET:S/install//} ] ; then \
+ echo "You must first build a kernel first." ; \
exit 1 ; \
fi
-.if ${KERNFORMAT} == "elf" && !defined(FORCE)
- @if [ -f /${KERNEL} -a "`file /${KERNEL} 2>/dev/null | grep ELF`" = "" ]; then \
- echo "WARNING: You are about to install an ELF kernel for the first time!" ; \
- echo "Please be sure you have upgraded your bootblocks and/or /boot/loader so" ; \
- echo "that you can boot it. Old bootblocks WILL NOT WORK! Please read:" ; \
- echo "http://www.freebsd.org/~peter/elfday.html for information." ; \
- echo "If you are satisfied you can boot an ELF kernel, type: make -DFORCE install" ; \
- exit 1 ; \
- fi
-.endif
.if exists(${DESTDIR}/${KERNEL})
-chflags noschg ${DESTDIR}/${KERNEL}
mv ${DESTDIR}/${KERNEL} ${DESTDIR}/${KERNEL}.old
@@ -261,7 +242,8 @@ ${INSTALL}:
mv -f /var/db/kvm_kernel.db /var/db/kvm_kernel.old.db ; \
fi \
fi
- install -c -m 555 -o root -g wheel -fschg ${FULLKERNEL} ${DESTDIR}/${KERNEL}
+ install -c -m 555 -o root -g wheel -fschg \
+ ${KERNEL}${.TARGET:S/install//} ${DESTDIR}/${KERNEL}
config.o:
${NORMAL_C}
diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98
index b85515c..65d2f09 100644
--- a/sys/pc98/conf/files.pc98
+++ b/sys/pc98/conf/files.pc98
@@ -3,7 +3,7 @@
#
# modified for PC-9801
#
-# $Id: files.pc98,v 1.88 1999/04/02 08:51:06 kato Exp $
+# $Id: files.pc98,v 1.89 1999/04/10 04:42:46 kato Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -26,6 +26,16 @@ font8x16.o optional std8x16font \
no-implicit-rule before-depend \
clean "${STD8X16FONT}-8x16 font8x16.c"
#
+atkbdmap.h optional atkbd_dflt_keymap \
+ compile-with "kbdcontrol -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \
+ no-obj no-implicit-rule before-depend \
+ clean "atkbdmap.h"
+#
+ukbdmap.h optional ukbd_dflt_keymap \
+ compile-with "kbdcontrol -L ${UKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > ukbdmap.h" \
+ no-obj no-implicit-rule before-depend \
+ clean "ukbdmap.h"
+#
dev/ata/ata-all.c optional ata device-driver
dev/ata/ata-dma.c optional ata device-driver
dev/ata/atapi-all.c optional ata device-driver
@@ -43,7 +53,7 @@ i386/apm/apm_setup.s optional apm
i386/eisa/dpt_eisa.c optional eisa dpt device-driver
i386/eisa/3c5x9.c optional ep device-driver
#i386/eisa/adv_eisa.c optional adv device-driver
-i386/eisa/ahc_eisa.c optional ahc device-driver \
+i386/eisa/ahc_eisa.c optional eisa ahc device-driver \
dependency "aic7xxx_reg.h $S/i386/eisa/ahc_eisa.c"
i386/eisa/ahb.c optional ahb device-driver
i386/eisa/bt_eisa.c optional bt device-driver
@@ -76,12 +86,14 @@ i386/i386/mp_machdep.c optional smp
i386/i386/mpapic.c optional smp
i386/i386/mpboot.s optional smp
i386/i386/mplock.s optional smp
+i386/i386/nexus.c standard
i386/i386/perfmon.c optional perfmon profiling-routine
i386/i386/perfmon.c optional perfmon
i386/i386/pmap.c standard
i386/i386/procfs_machdep.c standard
i386/i386/simplelock.s optional smp
i386/i386/support.s standard
+i386/i386/swapgeneric.c standard
i386/i386/swtch.s standard
i386/i386/sys_machdep.c standard
i386/i386/trap.c standard
@@ -112,7 +124,7 @@ i386/isa/bs/bs.c optional bs device-driver
i386/isa/bs/bsfunc.c optional bs device-driver
i386/isa/bs/bshw.c optional bs device-driver
i386/isa/bs/bsif.c optional bs device-driver
-#i386/isa/adv_isa.c optional adv device-driver
+i386/isa/adv_isa.c optional adv device-driver
#i386/isa/aha1542.c optional aha device-driver
i386/isa/aha_isa.c optional aha device-driver
i386/isa/bt_isa.c optional bt device-driver
@@ -156,7 +168,7 @@ contrib/dev/oltr/trlldbm.c optional oltr device-driver
i386/isa/ipl_funcs.c standard \
compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} $<"
i386/isa/intr_machdep.c standard
-pc98/pc98/pc98.c optional isa device-driver
+i386/isa/isa.c optional isa device-driver
i386/isa/istallion.c optional stli device-driver
i386/isa/joy.c optional joy device-driver
pc98/pc98/pc98kbd.c optional pckbd device-driver
@@ -169,20 +181,22 @@ pc98/pc98/npx.c mandatory npx device-driver
pc98/pc98/pc98gdc.c optional gdc device-driver
pc98/pc98/pcaudio.c optional pca device-driver
i386/isa/matcd/matcd.c optional matcd device-driver
+i386/isa/isa_compat.c optional isa device-driver
+pc98/pc98/isa_dma.c optional isa device-driver
i386/isa/pcibus.c optional pci device-driver
i386/isa/pcicx.c optional ze device-driver
i386/isa/pcicx.c optional zp device-driver
-#i386/isa/pcvt/pcvt_drv.c optional vt device-driver
-#i386/isa/pcvt/pcvt_ext.c optional vt device-driver
-#i386/isa/pcvt/pcvt_kbd.c optional vt device-driver
-#i386/isa/pcvt/pcvt_out.c optional vt device-driver
-#i386/isa/pcvt/pcvt_sup.c optional vt device-driver
-#i386/isa/pcvt/pcvt_vtf.c optional vt device-driver
+i386/isa/pcvt/pcvt_drv.c optional vt device-driver
+i386/isa/pcvt/pcvt_ext.c optional vt device-driver
+i386/isa/pcvt/pcvt_kbd.c optional vt device-driver
+i386/isa/pcvt/pcvt_out.c optional vt device-driver
+i386/isa/pcvt/pcvt_sup.c optional vt device-driver
+i386/isa/pcvt/pcvt_vtf.c optional vt device-driver
i386/isa/pnp.c optional pnp device-driver
i386/isa/prof_machdep.c optional profiling-routine
i386/isa/ppc.c optional ppc device-driver
i386/isa/pcf.c optional pcf device-driver
-i386/isa/psm.c optional psm device-driver
+isa/psm.c optional psm device-driver
i386/isa/random_machdep.c standard
i386/isa/rc.c optional rc device-driver
i386/isa/rp.c optional rp device-driver
@@ -264,13 +278,10 @@ pc98/pc98/spkr.c optional speaker device-driver
i386/isa/stallion.c optional stl device-driver
pc98/pc98/syscons.c optional sc device-driver
pc98/pc98/scvidctl.c optional sc device-driver
-#i386/isa/scvesactl.c optional sc device-driver
-#i386/isa/videoio.c optional sc device-driver
-#i386/isa/vesa.c optional sc device-driver
i386/isa/tw.c optional tw device-driver
pc98/pc98/wd.c optional wdc device-driver
pc98/pc98/wd.c optional wd device-driver
-i386/isa/atapi.c optional atapi device-driver
+i386/isa/atapi.c optional wdc device-driver
i386/isa/atapi-cd.c optional wcd device-driver
i386/isa/wfd.c optional wfd device-driver
i386/isa/wst.c optional wst device-driver
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index 9e45a0b..9c61ad2 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.82 1999/03/10 14:51:52 kato Exp $
+# $Id: options.pc98,v 1.83 1999/03/17 09:00:33 kato Exp $
DISABLE_PSE
IDE_DELAY
@@ -75,8 +75,6 @@ SC_MOUSE_CHAR opt_syscons.h
FB_INSTALL_CDEV opt_fb.h
-VESA opt_vesa.h
-
GDC opt_gdc.h
PSM_HOOKAPM opt_psm.h
@@ -92,11 +90,6 @@ KBD_MAXWAIT opt_kbd.h
KBD_RESETDELAY opt_kbd.h
KBDIO_DEBUG opt_kbd.h
-ATAPI opt_atapi.h
-ATAPI_STATIC opt_atapi.h
-
-CMD640 opt_wd.h
-
USERCONFIG opt_userconfig.h
VISUAL_USERCONFIG opt_userconfig.h
INTRO_USERCONFIG opt_userconfig.h
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
index 812c577..61950da 100644
--- a/sys/pc98/i386/machdep.c
+++ b/sys/pc98/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.110 1999/03/06 09:43:01 kato Exp $
+ * $Id: machdep.c,v 1.111 1999/04/03 22:20:02 jdp Exp $
*/
#include "apm.h"
@@ -71,6 +71,7 @@
#include <sys/sysent.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
+#include <sys/bus.h>
#ifdef SYSVSHM
#include <sys/shm.h>
@@ -125,7 +126,9 @@
#include <machine/perfmon.h>
#endif
+#ifdef OLD_BUS_ARCH
#include <i386/isa/isa_device.h>
+#endif
#include <i386/isa/intr_machdep.h>
#ifdef PC98
#include <pc98/pc98/pc98_machdep.h>
@@ -153,7 +156,7 @@ SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
static MALLOC_DEFINE(M_MBUF, "mbuf", "mbuf");
#ifdef PC98
-int need_pre_dma_flush; /* If 1, use wbinvd befor DMA transfer. */
+int need_pre_dma_flush; /* If 1, use wbinvd befor DMA transfer. */
int need_post_dma_flush; /* If 1, use invd after DMA transfer. */
#endif
@@ -169,9 +172,9 @@ SYSCTL_INT(_debug, OID_AUTO, tlb_flush_count,
#endif
#ifdef PC98
-int ispc98 = 1;
+static int ispc98 = 1;
#else
-int ispc98 = 0;
+static int ispc98 = 0;
#endif
SYSCTL_INT(_machdep, OID_AUTO, ispc98, CTLFLAG_RD, &ispc98, 0, "");
@@ -850,6 +853,9 @@ setregs(p, entry, stack, ps_strings)
regs->tf_es = _udatasel;
regs->tf_cs = _ucodesel;
+ /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */
+ regs->tf_ebx = ps_strings;
+
/* reset %fs and %gs as well */
pcb->pcb_fs = _udatasel;
pcb->pcb_gs = _udatasel;
@@ -1174,8 +1180,10 @@ init386(first)
unsigned biosbasemem, biosextmem;
struct gate_descriptor *gdp;
int gsel_tss;
+#if NNPX > 0
+ int msize;
+#endif
- struct isa_device *idp;
#ifndef SMP
/* table descriptors - used to load tables by microp */
struct region_descriptor r_gdt, r_idt;
@@ -1478,10 +1486,11 @@ init386(first)
#endif
#if NNPX > 0
- idp = find_isadev(isa_devtab_null, &npxdriver, 0);
- if (idp != NULL && idp->id_msize != 0) {
- Maxmem = idp->id_msize / 4;
- speculative_mprobe = FALSE;
+ if (resource_int_value("npx", 0, "msize", &msize) == 0) {
+ if (msize != 0) {
+ Maxmem = msize / 4;
+ speculative_mprobe = FALSE;
+ }
}
#endif
diff --git a/sys/pc98/i386/userconfig.c b/sys/pc98/i386/userconfig.c
index 1bb9377..a74a529 100644
--- a/sys/pc98/i386/userconfig.c
+++ b/sys/pc98/i386/userconfig.c
@@ -1,6 +1,6 @@
/**
** Copyright (c) 1995
- ** Michael Smith, msmith@atrad.adelaide.edu.au. All rights reserved.
+ ** Michael Smith, msmith@freebsd.org. All rights reserved.
**
** This code contains a module marked :
@@ -46,7 +46,7 @@
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
- ** $Id: userconfig.c,v 1.70 1999/02/25 11:05:50 kato Exp $
+ ** $Id: userconfig.c,v 1.71 1999/04/10 04:44:33 kato Exp $
**/
/**
@@ -119,11 +119,13 @@
#include <sys/reboot.h>
#include <sys/linker.h>
#include <sys/sysctl.h>
+#include <sys/bus.h>
#include <machine/cons.h>
#include <machine/md_var.h>
#include <machine/limits.h>
+
#include <i386/isa/isa_device.h>
#include "pnp.h"
@@ -136,11 +138,17 @@
static MALLOC_DEFINE(M_DEVL, "isa_devlist", "isa_device lists in userconfig()");
static struct isa_device *isa_devlist; /* list read by kget to extract changes */
+static struct isa_device *isa_devtab; /* fake isa_device table */
+static struct isa_driver *isa_drvtab; /* fake driver list */
static int userconfig_boot_parsing; /* set if we are reading from the boot instructions */
#define putchar(x) cnputc(x)
+static void load_devtab(void);
+static void free_devtab(void);
+static void save_resource(struct isa_device *);
+
static int
sysctl_machdep_uc_devlist SYSCTL_HANDLER_ARGS
{
@@ -283,8 +291,6 @@ getchar(void)
#endif
#ifdef VISUAL_USERCONFIG
-static struct isa_device *devtabs[] = { isa_devtab_bio, isa_devtab_tty, isa_devtab_net,
- isa_devtab_cam, isa_devtab_null, NULL };
typedef struct
{
@@ -403,6 +409,7 @@ static DEV_INFO device_info[] = {
{"vr", "VIA Rhine/Rhine II ethernet adapter", FLG_FIXED, CLS_NETWORK},
{"wb", "Winbond W89C840F ethernet adapter", FLG_FIXED, CLS_NETWORK},
{"xl", "3COM 3C90x PCI ethernet adapter", FLG_FIXED, CLS_NETWORK},
+{"rdp", "RealTek RTL8002 Pocket Ethernet", 0, CLS_NETWORK},
{"sio", "8250/16450/16550 Serial port", 0, CLS_COMMS},
{"cx", "Cronyx/Sigma multiport sync/async adapter",0, CLS_COMMS},
@@ -431,11 +438,7 @@ static DEV_INFO device_info[] = {
{"sc", "Syscons console driver", FLG_IMMUTABLE, CLS_INPUT},
{"bktr", "Brooktree BT848 based frame grabber/tuner card", 0,CLS_MMEDIA},
-#ifdef PC98
-{"pcm", "PC-9801-86 Sound Board", 0, CLS_MMEDIA},
-#else
{"pcm", "New Luigi audio driver for all supported sound cards", 0,CLS_MMEDIA},
-#endif
{"sb", "Soundblaster PCM (SB, SBPro, SB16, ProAudio Spectrum)",0,CLS_MMEDIA},
{"sbxvi", "Soundblaster 16", 0, CLS_MMEDIA},
{"sbmidi", "Soundblaster MIDI interface", 0, CLS_MMEDIA},
@@ -445,6 +448,7 @@ static DEV_INFO device_info[] = {
{"gusxvi", "Gravis Ultrasound 16-bit PCM", 0, CLS_MMEDIA},
{"gusmax", "Gravis Ultrasound MAX", 0, CLS_MMEDIA},
{"mss", "Microsoft Sound System", 0, CLS_MMEDIA},
+{"nss", "PC-9801-86 Sound Board", 0, CLS_MMEDIA},
{"opl", "OPL-2/3 FM, Soundblaster, SBPro, SB16, ProAudio Spectrum",0,CLS_MMEDIA},
{"mpu", "Roland MPU401 MIDI", 0, CLS_MMEDIA},
{"sscape", "Ensoniq Soundscape MIDI interface", 0, CLS_MMEDIA},
@@ -556,12 +560,10 @@ setdev(DEV_LIST *dev, int enabled)
static void
getdevs(void)
{
- int i,j;
+ int i;
struct isa_device *ap;
- for (j = 0; devtabs[j]; j++) /* ISA devices */
- {
- ap = devtabs[j]; /* pointer to array of devices */
+ ap = isa_devtab; /* pointer to array of devices */
for (i = 0; ap[i].id_id; i++) /* for each device in this table */
{
scratch.unit = ap[i].id_unit; /* device parameters */
@@ -581,7 +583,6 @@ getdevs(void)
if (!devinfo(&scratch)) /* get more info on the device */
insdev(&scratch,ap[i].id_enabled?active:inactive);
}
- }
#if NPCI > 0
for (i = 0; i < pcidevice_set.ls_length; i++)
{
@@ -865,6 +866,7 @@ savelist(DEV_LIST *list, int active)
{
id_pn = id_p->id_next;
bcopy(list->device,id_p,sizeof(struct isa_device));
+ save_resource(list->device);
id_p->id_next = id_pn;
break;
}
@@ -873,6 +875,7 @@ savelist(DEV_LIST *list, int active)
{
id_pn = malloc(sizeof(struct isa_device),M_DEVL,M_WAITOK);
bcopy(list->device,id_pn,sizeof(struct isa_device));
+ save_resource(list->device);
id_pn->id_next = isa_devlist;
isa_devlist = id_pn; /* park at top of list */
}
@@ -2528,7 +2531,7 @@ visuserconfig(void)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: userconfig.c,v 1.70 1999/02/25 11:05:50 kato Exp $
+ * $Id: userconfig.c,v 1.71 1999/04/10 04:44:33 kato Exp $
*/
#include "scbus.h"
@@ -2677,6 +2680,7 @@ userconfig(void)
int rval;
Cmd *cmd;
+ load_devtab();
init_config_script();
while (1) {
@@ -2711,8 +2715,10 @@ userconfig(void)
continue;
}
rval = (*cmd->handler)(cmd->parms);
- if (rval)
+ if (rval) {
+ free_devtab();
return;
+ }
}
}
@@ -2810,11 +2816,7 @@ static int
list_devices(CmdParm *parms)
{
lineno = 0;
- if (lsdevtab(&isa_devtab_bio[0])) return 0;
- if (lsdevtab(&isa_devtab_tty[0])) return 0;
- if (lsdevtab(&isa_devtab_net[0])) return 0;
- if (lsdevtab(&isa_devtab_cam[0])) return 0;
- if (lsdevtab(&isa_devtab_null[0])) return 0;
+ if (lsdevtab(isa_devtab)) return 0;
#if NPNP > 0
if (lspnp()) return 0;
#endif
@@ -3334,20 +3336,65 @@ lsdevtab(struct isa_device *dt)
return(0);
}
+static void
+load_devtab(void)
+{
+ int i, val;
+ int count = resource_count();
+ int id = 1;
+ int dt;
+ char *name;
+ int unit;
+
+ isa_devtab = malloc(sizeof(struct isa_device)*(count + 1),M_DEVL,M_WAITOK);
+ isa_drvtab = malloc(sizeof(struct isa_driver)*(count + 1),M_DEVL,M_WAITOK);
+ bzero(isa_devtab, sizeof(struct isa_device) * (count + 1));
+ bzero(isa_drvtab, sizeof(struct isa_driver) * (count + 1));
+ dt = 0;
+ for (i = 0; i < count; i++) {
+ name = resource_query_name(i);
+ unit = resource_query_unit(i);
+ if (unit < 0)
+ continue; /* skip wildcards */
+ isa_devtab[dt].id_id = id++;
+ isa_devtab[dt].id_driver = &isa_drvtab[dt];
+ resource_int_value(name, unit, "port", &isa_devtab[dt].id_iobase);
+ val = 0;
+ resource_int_value(name, unit, "irq", &val);
+ isa_devtab[dt].id_irq = (1 << val);
+ resource_int_value(name, unit, "drq", &isa_devtab[dt].id_drq);
+ resource_int_value(name, unit, "maddr",(int *)&isa_devtab[dt].id_maddr);
+ resource_int_value(name, unit, "msize", &isa_devtab[dt].id_msize);
+ isa_devtab[dt].id_unit = unit;
+ resource_int_value(name, unit, "flags", &isa_devtab[dt].id_flags);
+ val = 0;
+ resource_int_value(name, unit, "disabled", &val);
+ isa_devtab[dt].id_enabled = !val;
+ isa_drvtab[dt].name = malloc(strlen(name) + 1, M_DEVL,M_WAITOK);
+ strcpy(isa_drvtab[dt].name, name);
+ dt++;
+ }
+}
+
+static void
+free_devtab(void)
+{
+ int i;
+ int count = resource_count();
+
+ for (i = 0; i < count; i++)
+ if (isa_drvtab[i].name)
+ free(isa_drvtab[i].name, M_DEVL);
+ free(isa_drvtab, M_DEVL);
+ free(isa_devtab, M_DEVL);
+}
+
static struct isa_device *
find_device(char *devname, int unit)
{
struct isa_device *ret;
- if ((ret = search_devtable(&isa_devtab_bio[0], devname, unit)) != NULL)
- return ret;
- if ((ret = search_devtable(&isa_devtab_tty[0], devname, unit)) != NULL)
- return ret;
- if ((ret = search_devtable(&isa_devtab_net[0], devname, unit)) != NULL)
- return ret;
- if ((ret = search_devtable(&isa_devtab_cam[0], devname, unit)) != NULL)
- return ret;
- if ((ret = search_devtable(&isa_devtab_null[0], devname, unit)) != NULL)
+ if ((ret = search_devtable(isa_devtab, devname, unit)) != NULL)
return ret;
return NULL;
}
@@ -3554,6 +3601,29 @@ list_scsi(CmdParm *parms)
}
#endif
+static void
+save_resource(struct isa_device *idev)
+{
+ int i;
+ char *name;
+ int unit;
+ int count = resource_count();
+
+ for (i = 0; i < count; i++) {
+ name = resource_query_name(i);
+ unit = resource_query_unit(i);
+ if (strcmp(name, idev->id_driver->name) || unit != idev->id_unit)
+ continue;
+ resource_set_int(i, "port", isa_devtab[i].id_iobase);
+ resource_set_int(i, "irq", (1 << isa_devtab[i].id_irq));
+ resource_set_int(i, "drq", isa_devtab[i].id_drq);
+ resource_set_int(i, "maddr", (int)isa_devtab[i].id_maddr);
+ resource_set_int(i, "msize", isa_devtab[i].id_msize);
+ resource_set_int(i, "flags", isa_devtab[i].id_flags);
+ resource_set_int(i, "disabled", !isa_devtab[i].id_enabled);
+ }
+}
+
static int
save_dev(idev)
struct isa_device *idev;
@@ -3566,6 +3636,7 @@ struct isa_device *idev;
if (id_p->id_id == idev->id_id) {
id_pn = id_p->id_next;
bcopy(idev,id_p,sizeof(struct isa_device));
+ save_resource(idev);
id_p->id_next = id_pn;
return 1;
}
diff --git a/sys/pc98/pc98/fd.c b/sys/pc98/pc98/fd.c
index c70dc56..7d6c8bb 100644
--- a/sys/pc98/pc98/fd.c
+++ b/sys/pc98/pc98/fd.c
@@ -47,7 +47,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.52 1999/02/10 00:03:58 ken Exp $
+ * $Id: fd.c,v 1.53 1999/04/06 03:12:22 peter Exp $
*
*/
@@ -60,33 +60,44 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <machine/clock.h>
-#include <machine/ioctl_fd.h>
#include <sys/disklabel.h>
-#include <sys/buf.h>
#include <sys/devicestat.h>
+#include <sys/fcntl.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/proc.h>
#include <sys/syslog.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/clock.h>
+#include <machine/ioctl_fd.h>
+#include <machine/resource.h>
+#include <machine/stdarg.h>
+
+#ifdef DEVFS
+#include <sys/devfsext.h>
+#endif /* DEVFS */
+
+#include <isa/isavar.h>
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
#include <pc98/pc98/epsonio.h>
-#include <i386/isa/isa_device.h>
+#include <i386/isa/isa_dma.h>
#include <pc98/pc98/fdreg.h>
#else
#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
+#include <i386/isa/isa_dma.h>
#include <i386/isa/fdreg.h>
-#include <i386/isa/rtc.h>
#endif
#include <i386/isa/fdc.h>
-#include <machine/stdarg.h>
-#ifdef DEVFS
-#include <sys/devfsext.h>
-#endif /* DEVFS */
+#include <i386/isa/rtc.h>
/* misuse a flag to identify format operation */
#define B_FORMAT B_XXX
@@ -188,13 +199,13 @@ static struct fd_type fd_types[NUMTYPES] =
/***********************************************************************\
* Per controller structure. *
\***********************************************************************/
-struct fdc_data fdc_data[NFDC];
+static devclass_t fdc_devclass;
/***********************************************************************\
* Per drive structure. *
* N per controller (DRVS_PER_CTLR) *
\***********************************************************************/
-static struct fd_data {
+struct fd_data {
struct fdc_data *fdc; /* pointer to controller structure */
int fdsu; /* this units number on this controller */
int type; /* Drive type (FD_1440...) */
@@ -219,7 +230,10 @@ static struct fd_data {
#ifdef PC98
int pc98_trans;
#endif
-} fd_data[NFD];
+ device_t dev;
+ fdu_t fdu;
+};
+static devclass_t fd_devclass;
#ifdef EPSON_NRDISK
typedef unsigned int nrd_t;
@@ -290,29 +304,26 @@ nrd_info(addr)
static int yeattach(struct isa_device *);
#endif
-/* autoconfig functions */
-static int fdprobe(struct isa_device *);
-static int fdattach(struct isa_device *);
-
/* needed for ft driver, thus exported */
-int in_fdc(fdcu_t);
-int out_fdc(fdcu_t, int);
+int in_fdc(struct fdc_data *);
+int out_fdc(struct fdc_data *, int);
/* internal functions */
-static void set_motor(fdcu_t, int, int);
+static void fdc_add_device(device_t, const char *, int);
+static void fdc_intr(void *);
+static void set_motor(struct fdc_data *, int, int);
# define TURNON 1
# define TURNOFF 0
static timeout_t fd_turnoff;
static timeout_t fd_motor_on;
-static void fd_turnon(fdu_t);
+static void fd_turnon(struct fd_data *);
static void fdc_reset(fdc_p);
-static int fd_in(fdcu_t, int *);
-static void fdstart(fdcu_t);
+static int fd_in(struct fdc_data *, int *);
+static void fdstart(struct fdc_data *);
static timeout_t fd_iotimeout;
static timeout_t fd_pseudointr;
-static ointhand2_t fdintr;
-static int fdstate(fdcu_t, fdc_p);
-static int retrier(fdcu_t);
+static int fdstate(struct fdc_data *);
+static int retrier(struct fdc_data *);
static int fdformat(dev_t, struct fd_formb *, struct proc *);
static int enable_fifo(fdc_p fdc);
@@ -451,13 +462,6 @@ static int yeintr(struct pccard_devinfo *devi)
#endif /* NCARD > 0 */
#endif /* FDC_YE */
-
-/* autoconfig structure */
-
-struct isa_driver fdcdriver = {
- fdprobe, fdattach, "fdc",
-};
-
static d_open_t Fdopen; /* NOTE, not fdopen */
static d_read_t fdread;
static d_write_t fdwrite;
@@ -469,28 +473,18 @@ static d_strategy_t fdstrategy;
#define CDEV_MAJOR 9
#define BDEV_MAJOR 2
-
-static struct cdevsw fd_cdevsw = {
- Fdopen, fdclose, fdread, fdwrite,
- fdioctl, nostop, nullreset, nodevtotty,
- seltrue, nommap, fdstrategy, "fd",
- NULL, -1, nodump, nopsize,
- D_DISK, 0, -1 };
-
-
-static struct isa_device *fdcdevs[NFDC];
-
-
static int
-fdc_err(fdcu_t fdcu, const char *s)
+fdc_err(struct fdc_data *fdc, const char *s)
{
- fdc_data[fdcu].fdc_errs++;
- if(s) {
- if(fdc_data[fdcu].fdc_errs < FDC_ERRMAX)
- printf("fdc%d: %s", fdcu, s);
- else if(fdc_data[fdcu].fdc_errs == FDC_ERRMAX)
- printf("fdc%d: too many errors, not logging any more\n",
- fdcu);
+ fdc->fdc_errs++;
+ if (s) {
+ if (fdc->fdc_errs < FDC_ERRMAX) {
+ device_print_prettyname(fdc->fdc_dev);
+ printf("%s", s);
+ } else if (fdc->fdc_errs == FDC_ERRMAX) {
+ device_print_prettyname(fdc->fdc_dev);
+ printf("too many errors, not logging any more\n");
+ }
}
return FD_FAILED;
@@ -502,9 +496,8 @@ fdc_err(fdcu_t fdcu, const char *s)
* # of output bytes, output bytes as ints ...,
* # of input bytes, input bytes as ints ...
*/
-
static int
-fd_cmd(fdcu_t fdcu, int n_out, ...)
+fd_cmd(struct fdc_data *fdc, int n_out, ...)
{
u_char cmd;
int n_in;
@@ -517,26 +510,26 @@ fd_cmd(fdcu_t fdcu, int n_out, ...)
va_start(ap, n_out);
for (n = 0; n < n_out; n++)
{
- if (out_fdc(fdcu, va_arg(ap, int)) < 0)
+ if (out_fdc(fdc, va_arg(ap, int)) < 0)
{
char msg[50];
snprintf(msg, sizeof(msg),
"cmd %x failed at out byte %d of %d\n",
cmd, n + 1, n_out);
- return fdc_err(fdcu, msg);
+ return fdc_err(fdc, msg);
}
}
n_in = va_arg(ap, int);
for (n = 0; n < n_in; n++)
{
int *ptr = va_arg(ap, int *);
- if (fd_in(fdcu, ptr) < 0)
+ if (fd_in(fdc, ptr) < 0)
{
char msg[50];
snprintf(msg, sizeof(msg),
"cmd %02x failed at in byte %d of %d\n",
cmd, n + 1, n_in);
- return fdc_err(fdcu, msg);
+ return fdc_err(fdc, msg);
}
}
@@ -557,8 +550,8 @@ enable_fifo(fdc_p fdc)
* first byte, and check for an early turn of data directon.
*/
- if (out_fdc(fdc->fdcu, I8207X_CONFIGURE) < 0)
- return fdc_err(fdc->fdcu, "Enable FIFO failed\n");
+ if (out_fdc(fdc, I8207X_CONFIGURE) < 0)
+ return fdc_err(fdc, "Enable FIFO failed\n");
/* If command is invalid, return */
j = 100000;
@@ -569,17 +562,17 @@ enable_fifo(fdc_p fdc)
return FD_FAILED;
}
if (j<0 ||
- fd_cmd(fdc->fdcu, 3,
+ fd_cmd(fdc, 3,
0, (fifo_threshold - 1) & 0xf, 0, 0) < 0) {
fdc_reset(fdc);
- return fdc_err(fdc->fdcu, "Enable FIFO failed\n");
+ return fdc_err(fdc, "Enable FIFO failed\n");
}
fdc->flags |= FDC_HAS_FIFO;
return 0;
}
- if (fd_cmd(fdc->fdcu, 4,
+ if (fd_cmd(fdc, 4,
I8207X_CONFIGURE, 0, (fifo_threshold - 1) & 0xf, 0, 0) < 0)
- return fdc_err(fdc->fdcu, "Re-enable FIFO failed\n");
+ return fdc_err(fdc, "Re-enable FIFO failed\n");
return 0;
}
@@ -588,9 +581,9 @@ fd_sense_drive_status(fdc_p fdc, int *st3p)
{
int st3;
- if (fd_cmd(fdc->fdcu, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
+ if (fd_cmd(fdc, 2, NE7CMD_SENSED, fdc->fdu, 1, &st3))
{
- return fdc_err(fdc->fdcu, "Sense Drive Status failed\n");
+ return fdc_err(fdc, "Sense Drive Status failed\n");
}
if (st3p)
*st3p = st3;
@@ -601,7 +594,7 @@ fd_sense_drive_status(fdc_p fdc, int *st3p)
static int
fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
{
- int st0, cyl;
+ int cyl, st0, ret;
#ifdef EPSON_NRDISK
if (fdc->fdu == nrdu) {
@@ -612,11 +605,9 @@ fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
}
else {
#endif /* EPSON_NRDISK */
- int ret = fd_cmd(fdc->fdcu, 1, NE7CMD_SENSEI, 1, &st0);
-
- if (ret)
- {
- (void)fdc_err(fdc->fdcu,
+ ret = fd_cmd(fdc, 1, NE7CMD_SENSEI, 1, &st0);
+ if (ret) {
+ (void)fdc_err(fdc,
"sense intr err reading stat reg 0\n");
return ret;
}
@@ -624,17 +615,15 @@ fd_sense_int(fdc_p fdc, int *st0p, int *cylp)
if (st0p)
*st0p = st0;
- if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV)
- {
+ if ((st0 & NE7_ST0_IC) == NE7_ST0_IC_IV) {
/*
* There doesn't seem to have been an interrupt.
*/
return FD_NOT_VALID;
}
- if (fd_in(fdc->fdcu, &cyl) < 0)
- {
- return fdc_err(fdc->fdcu, "can't get cyl num\n");
+ if (fd_in(fdc, &cyl) < 0) {
+ return fdc_err(fdc, "can't get cyl num\n");
}
if (cylp)
@@ -652,8 +641,7 @@ fd_read_status(fdc_p fdc, int fdsu)
{
int i, ret;
- for (i = 0; i < 7; i++)
- {
+ for (i = 0; i < 7; i++) {
/*
* XXX types are poorly chosen. Only bytes can by read
* from the hardware, but fdc->status[] wants u_ints and
@@ -677,7 +665,7 @@ fd_read_status(fdc_p fdc, int fdsu)
}
else {
#endif /* EPSON_NRDISK */
- ret = fd_in(fdc->fdcu, &status);
+ ret = fd_in(fdc, &status);
fdc->status[i] = status;
if (ret != 0)
break;
@@ -701,26 +689,19 @@ fd_read_status(fdc_p fdc, int fdsu)
static int pc98_trans = 0; /* 0 : HD , 1 : DD , 2 : 1.44 */
static int pc98_trans_prev = 0;
-static void set_density(fdcu_t, fdu_t);
-static int pc98_fd_check_ready(fdu_t);
-
-static void set_density(fdcu, fdu)
- fdcu_t fdcu;
- fdu_t fdu;
+static void set_density(fdc_p fdc)
{
/* always motor on */
- outb(IO_FDPORT,
- (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
+ outb(IO_FDPORT, (pc98_trans != 1 ? FDP_FDDEXC : 0) | FDP_PORTEXC);
DELAY(100);
- outb(fdc_data[fdcu].baseport + FDOUT, FDO_RST | FDO_DMAE);
+ outb(fdc->baseport + FDOUT, FDO_RST | FDO_DMAE);
/* in the case of note W, always inhibit 100ms timer */
}
-static int pc98_fd_check_ready(fdu)
- fdu_t fdu;
+static int pc98_fd_check_ready(fdu_t fdu)
{
- fd_p fd = fd_data + fdu;
- fdcu_t fdcu = fd->fdc->fdcu;
+ fd_p fd = devclass_get_softc(fd_devclass, fdu);
+ struct fdc_data *fdc = fd->fdc;
int retry = 0;
#ifdef EPSON_NRDISK
@@ -730,13 +711,13 @@ static int pc98_fd_check_ready(fdu)
}
#endif
while (retry++ < 30000) {
- set_motor(fdcu, fd->fdsu, TURNON);
- out_fdc(fdcu, NE7CMD_SENSED); /* Sense Drive Status */
+ set_motor(fdc, fd->fdsu, TURNON);
+ out_fdc(fdc, NE7CMD_SENSED); /* Sense Drive Status */
DELAY(100);
- out_fdc(fdcu, fdu); /* Drive number */
+ out_fdc(fdc, fdu); /* Drive number */
DELAY(100);
- if ((in_fdc(fdcu) & NE7_ST3_RD)){
- outb(fdc_data[fdcu].baseport + FDOUT,
+ if ((in_fdc(fdc) & NE7_ST3_RD)){
+ outb(fdc->baseport + FDOUT,
FDO_DMAE | FDO_MTON);
DELAY(10);
return 0;
@@ -746,43 +727,104 @@ static int pc98_fd_check_ready(fdu)
}
#endif
-
-/*
- * probe for existance of controller
- */
static int
-fdprobe(struct isa_device *dev)
+fdc_probe(device_t dev)
{
- fdcu_t fdcu = dev->id_unit;
- if(fdc_data[fdcu].flags & FDC_ATTACHED)
- {
- printf("fdc%d: unit used multiple times\n", fdcu);
- return 0;
+ int error, i, ic_type;
+ struct fdc_data *fdc;
+ char myname[8]; /* better be long enough */
+
+ fdc = device_get_softc(dev);
+ bzero(fdc, sizeof *fdc);
+ fdc->fdc_dev = dev;
+ fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0;
+ fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0;
+
+ fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
+ &fdc->rid_ioport, 0ul, ~0ul,
+ IO_FDCSIZE, RF_ACTIVE);
+ if (fdc->res_ioport == 0) {
+ device_print_prettyname(dev);
+ printf("cannot reserve I/O port range\n");
+ error = ENXIO;
+ goto out;
}
-
- fdcdevs[fdcu] = dev;
- fdc_data[fdcu].baseport = dev->id_iobase;
+ fdc->baseport = fdc->res_ioport->r_start;
+
+ fdc->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &fdc->rid_irq, 0ul, ~0ul, 1,
+ RF_ACTIVE);
+ if (fdc->res_irq == 0) {
+ device_print_prettyname(dev);
+ printf("cannot reserve interrupt line\n");
+ error = ENXIO;
+ goto out;
+ }
+ fdc->res_drq = bus_alloc_resource(dev, SYS_RES_DRQ,
+ &fdc->rid_drq, 0ul, ~0ul, 1,
+ RF_ACTIVE);
+ if (fdc->res_drq == 0) {
+ device_print_prettyname(dev);
+ printf("cannot reserve DMA request line\n");
+ error = ENXIO;
+ goto out;
+ }
+ fdc->dmachan = fdc->res_drq->r_start;
+ error = BUS_SETUP_INTR(device_get_parent(dev), dev,
+ fdc->res_irq, fdc_intr, fdc, &fdc->fdc_intr);
#ifndef PC98
/* First - lets reset the floppy controller */
- outb(dev->id_iobase+FDOUT, 0);
+ outb(fdc->baseport + FDOUT, 0);
DELAY(100);
- outb(dev->id_iobase+FDOUT, FDO_FRST);
+ outb(fdc->baseport + FDOUT, FDO_FRST);
#endif
/* see if it can handle a command */
#ifdef PC98
- if (fd_cmd(fdcu,
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
- 0))
+ if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(4, 240),
+ NE7_SPEC_2(2, 0), 0)) {
+ error = ENXIO;
+ goto out;
+ }
#else
- if (fd_cmd(fdcu,
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
- 0))
+ if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
+ NE7_SPEC_2(2, 0), 0)) {
+ error = ENXIO;
+ goto out;
+ }
#endif
- {
- return(0);
+
+#ifndef PC98
+ if (fd_cmd(fdc, 1, NE7CMD_VERSION, 1, &ic_type) == 0) {
+ ic_type = (u_char)ic_type;
+ switch (ic_type) {
+ case 0x80:
+ device_set_desc(dev, "NEC 765 or clone");
+ fdc->fdct = FDC_NE765;
+ break;
+ case 0x81:
+ device_set_desc(dev, "Intel 82077 or clone");
+ fdc->fdct = FDC_I82077;
+ break;
+ case 0x90:
+ device_set_desc(dev, "NEC 72065B or clone");
+ fdc->fdct = FDC_NE72065;
+ break;
+ default:
+ device_set_desc(dev, "generic floppy controller");
+ fdc->fdct = FDC_UNKNOWN;
+ break;
+ }
}
+#endif
+
+ snprintf(myname, sizeof(myname), "%s%d", device_get_name(dev),
+ device_get_unit(dev));
+ for (i = resource_query_string(-1, "at", myname); i != -1;
+ i = resource_query_string(i, "at", myname))
+ fdc_add_device(dev, resource_query_name(i),
+ resource_query_unit(i));
#ifdef FDC_YE
/*
* don't succeed on probe; wait
@@ -791,385 +833,413 @@ fdprobe(struct isa_device *dev)
if (dev->id_flags & FDC_IS_PCMCIA)
return(0);
#endif
- return (IO_FDCSIZE);
+ return (0);
+
+out:
+ if (fdc->fdc_intr)
+ BUS_TEARDOWN_INTR(device_get_parent(dev), dev, fdc->res_irq,
+ fdc->fdc_intr);
+ if (fdc->res_irq != 0) {
+ bus_deactivate_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
+ fdc->res_irq);
+ bus_release_resource(dev, SYS_RES_IRQ, fdc->rid_irq,
+ fdc->res_irq);
+ }
+ if (fdc->res_ioport != 0) {
+ bus_deactivate_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
+ fdc->res_ioport);
+ bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
+ fdc->res_ioport);
+ }
+ if (fdc->res_drq != 0) {
+ bus_deactivate_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
+ fdc->res_drq);
+ bus_release_resource(dev, SYS_RES_DRQ, fdc->rid_drq,
+ fdc->res_drq);
+ }
+ return (error);
}
/*
- * wire controller into system, look for floppy units
+ * Aped dfr@freebsd.org's isa_add_device().
*/
+static void
+fdc_add_device(device_t dev, const char *name, int unit)
+{
+ int disabled, *ivar;
+ device_t child;
+
+ ivar = malloc(sizeof *ivar, M_DEVBUF /* XXX */, M_NOWAIT);
+ if (ivar == 0)
+ return;
+ if (resource_int_value(name, unit, "drive", ivar) == 0)
+ *ivar = 0;
+ child = device_add_child(dev, name, unit, ivar);
+ if (child == 0)
+ return;
+ if (resource_int_value(name, unit, "disabled", &disabled) == 0)
+ device_disable(child);
+}
+
static int
-fdattach(struct isa_device *dev)
+fdc_attach(device_t dev)
{
- unsigned fdt;
- fdu_t fdu;
- fdcu_t fdcu = dev->id_unit;
- fdc_p fdc = fdc_data + fdcu;
- fd_p fd;
-#ifdef PC98
- int fdsu;
-#else
- int fdsu, st0, st3, i;
-#endif
- struct isa_device *fdup;
-#ifndef PC98
- int ic_type = 0;
-#endif
-#ifdef DEVFS
- int mynor;
- int typemynor;
- int typesize;
-#endif
+ struct fdc_data *fdc = device_get_softc(dev);
+ fdcu_t fdcu = device_get_unit(dev);
- dev->id_ointr = fdintr;
fdc->fdcu = fdcu;
fdc->flags |= FDC_ATTACHED;
-#ifdef PC98
- fdc->dmachan = 2;
- if (fdc->dmachan != dev->id_drq) {
- dev->id_drq = fdc->dmachan;
- printf(" [dma is changed to #%d]", fdc->dmachan);
- }
+
/* Acquire the DMA channel forever, The driver will do the rest */
+ /* XXX should integrate with rman */
isa_dma_acquire(fdc->dmachan);
isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
fdc->state = DEVIDLE;
+
+#ifdef PC98
+ /* reset controller, turn motor off, clear fdout mirror reg */
fdc_reset(fdc);
#else
- fdc->dmachan = dev->id_drq;
- /* Acquire the DMA channel forever, The driver will do the rest */
- isa_dma_acquire(fdc->dmachan);
- isa_dmainit(fdc->dmachan, 128 << 3 /* XXX max secsize */);
- fdc->state = DEVIDLE;
/* reset controller, turn motor off, clear fdout mirror reg */
outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
#endif
bufq_init(&fdc->head);
- /* check for each floppy drive */
- for (fdup = isa_biotab_fdc; fdup->id_driver != 0; fdup++) {
- if (fdup->id_iobase != dev->id_iobase)
- continue;
- fdu = fdup->id_unit;
- fd = &fd_data[fdu];
- if (fdu >= (NFD))
- continue;
- fdsu = fdup->id_physid;
- /* look up what bios thinks we have */
- switch (fdu) {
+#ifdef FIFO_BEFORE_MOTORON
+ /* Hmm, this doesn't work here - is set_motor() magic? -Peter */
+ if (fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN
+ && enable_fifo(fdc) == 0) {
+ device_print_prettyname(dev);
+ printf("FIFO enabled, %d bytes threshold\n", fifo_threshold);
+ }
+#endif
+ /*
+ * Probe and attach any children as were configured above.
+ */
+ return (bus_generic_attach(dev));
+}
+
+static void
+fdc_print_child(device_t me, device_t child)
+{
+ printf(" at %s%d drive %d", device_get_name(me), device_get_unit(me),
+ *(int *)device_get_ivars(child));
+}
+
+static int
+fd_probe(device_t dev)
+{
+ int i;
+ u_int fdt, st0, st3;
+ struct fd_data *fd;
+ struct fdc_data *fdc;
+ fdsu_t fdsu;
+#ifndef FIFO_BEFORE_MOTORON
+ static int fd_fifo = 0;
+#endif
+
+ fdsu = *(int *)device_get_ivars(dev); /* xxx cheat a bit... */
+ fd = device_get_softc(dev);
+ fdc = device_get_softc(device_get_parent(dev));
+
+ bzero(fd, sizeof *fd);
+ fd->dev = dev;
+ fd->fdc = fdc;
+ fd->fdsu = fdsu;
+ fd->fdu = device_get_unit(dev);
+
#ifdef PC98
- case 0: case 1: case 2: case 3:
- if ((PC98_SYSTEM_PARAMETER(0x5ae) >> fdu) & 0x01)
- fdt = FDT_144M;
+ /* look up what bios thinks we have */
+ switch (fd->fdu) {
+ case 0: case 1: case 2: case 3:
+ if ((PC98_SYSTEM_PARAMETER(0x5ae) >> fd->fdu) & 0x01)
+ fdt = FDT_144M;
#ifdef EPSON_NRDISK
- else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fdu) & 0x01) {
- fdt = FDT_12M;
- switch (epson_machine_id) {
- case 0x20: case 0x27:
- if ((PC98_SYSTEM_PARAMETER(0x488) >> fdu) & 0x01) {
- if (nrd_check_ready()) {
- nrd_LED_on();
- nrdu = fdu;
- }
- else fdt = FDT_NONE;
- }
+ else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fd->fdu) & 0x01) {
+ fdt = FDT_12M;
+ switch (epson_machine_id) {
+ case 0x20: case 0x27:
+ if ((PC98_SYSTEM_PARAMETER(0x488) >> fd->fdu) & 0x01) {
+ if (nrd_check_ready()) {
+ nrd_LED_on();
+ nrdu = fd->fdu;
+ } else {
+ fdt = FDT_NONE;
}
+ }
}
+ }
#else /* !EPSON_NRDISK */
- else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fdu) & 0x01) {
- fdt = FDT_12M;
- switch (epson_machine_id) {
- case 0x20: case 0x27:
- if ((PC98_SYSTEM_PARAMETER(0x488) >> fdu) & 0x01)
- fdt = FDT_NONE;
- }
+ else if ((PC98_SYSTEM_PARAMETER(0x55c) >> fd->fdu) & 0x01) {
+ fdt = FDT_12M;
+ switch (epson_machine_id) {
+ case 0x20: case 0x27:
+ if ((PC98_SYSTEM_PARAMETER(0x488) >> fd->fdu) & 0x01)
+ fdt = FDT_NONE;
}
+ }
#endif /* EPSON_NRDISK */
- else fdt = FDT_NONE;
- break;
- default:
+ else
fdt = FDT_NONE;
- break;
+ break;
+ default:
+ fdt = FDT_NONE;
+ break;
+ }
#else
- case 0: if (dev->id_flags & FDC_PRETEND_D0)
- fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED;
- else
- fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
- break;
- case 1: fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
- break;
- default: fdt = RTCFDT_NONE;
- break;
+ /* look up what bios thinks we have */
+ switch (fd->fdu) {
+ case 0:
+ if (isa_get_flags(fdc->fdc_dev) & FDC_PRETEND_D0)
+ fdt = RTCFDT_144M | RTCFDT_144M_PRETENDED;
+ else
+ fdt = (rtcin(RTC_FDISKETTE) & 0xf0);
+ break;
+ case 1:
+ fdt = ((rtcin(RTC_FDISKETTE) << 4) & 0xf0);
+ break;
+ default:
+ fdt = RTCFDT_NONE;
+ break;
+ }
#endif
- }
- /* is there a unit? */
+
+ /* is there a unit? */
#ifdef PC98
- if ((fdt == FDT_NONE)
+ if (fdt == FDT_NONE)
+ return (ENXIO);
#else
- if ((fdt == RTCFDT_NONE)
-#endif
- ) {
-#ifdef PC98
- fd->fdc = fdc;
+ if (fdt == RTCFDT_NONE)
+ return (ENXIO);
#endif
- fd->type = NO_TYPE;
- continue;
- }
#ifndef PC98
- /* select it */
- set_motor(fdcu, fdsu, TURNON);
- DELAY(1000000); /* 1 sec */
-
- if (ic_type == 0 &&
- fd_cmd(fdcu, 1, NE7CMD_VERSION, 1, &ic_type) == 0)
- {
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("fdc%d: ", fdcu);
-#endif
- ic_type = (u_char)ic_type;
- switch( ic_type ) {
- case 0x80:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("NEC 765\n");
-#endif
- fdc->fdct = FDC_NE765;
- break;
- case 0x81:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("Intel 82077\n");
-#endif
- fdc->fdct = FDC_I82077;
- break;
- case 0x90:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("NEC 72065B\n");
-#endif
- fdc->fdct = FDC_NE72065;
- break;
- default:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("unknown IC type %02x\n", ic_type);
+ /* select it */
+ set_motor(fdc, fdsu, TURNON);
+ DELAY(1000000); /* 1 sec */
+
+#ifndef FIFO_BEFORE_MOTORON
+ if (fd_fifo == 0 && fdc->fdct != FDC_NE765 && fdc->fdct != FDC_UNKNOWN
+ && enable_fifo(fdc) == 0) {
+ device_print_prettyname(device_get_parent(dev));
+ printf("FIFO enabled, %d bytes threshold\n", fifo_threshold);
+ }
+ fd_fifo = 1;
#endif
- fdc->fdct = FDC_UNKNOWN;
- break;
- }
- if (fdc->fdct != FDC_NE765 &&
- fdc->fdct != FDC_UNKNOWN &&
- enable_fifo(fdc) == 0) {
- printf("fdc%d: FIFO enabled", fdcu);
- printf(", %d bytes threshold\n",
- fifo_threshold);
- }
- }
- if ((fd_cmd(fdcu, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0) &&
- (st3 & NE7_ST3_T0)) {
- /* if at track 0, first seek inwards */
- /* seek some steps: */
- (void)fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0);
- DELAY(300000); /* ...wait a moment... */
- (void)fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
- }
- /* If we're at track 0 first seek inwards. */
- if ((fd_sense_drive_status(fdc, &st3) == 0) &&
- (st3 & NE7_ST3_T0)) {
- /* Seek some steps... */
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
- /* ...wait a moment... */
- DELAY(300000);
- /* make ctrlr happy: */
- (void)fd_sense_int(fdc, 0, 0);
- }
+ if ((fd_cmd(fdc, 2, NE7CMD_SENSED, fdsu, 1, &st3) == 0)
+ && (st3 & NE7_ST3_T0)) {
+ /* if at track 0, first seek inwards */
+ /* seek some steps: */
+ fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0);
+ DELAY(300000); /* ...wait a moment... */
+ fd_sense_int(fdc, 0, 0); /* make ctrlr happy */
+ }
+
+ /* If we're at track 0 first seek inwards. */
+ if ((fd_sense_drive_status(fdc, &st3) == 0) && (st3 & NE7_ST3_T0)) {
+ /* Seek some steps... */
+ if (fd_cmd(fdc, 3, NE7CMD_SEEK, fdsu, 10, 0) == 0) {
+ /* ...wait a moment... */
+ DELAY(300000);
+ /* make ctrlr happy: */
+ fd_sense_int(fdc, 0, 0);
}
+ }
- for(i = 0; i < 2; i++) {
- /*
- * we must recalibrate twice, just in case the
- * heads have been beyond cylinder 76, since most
- * FDCs still barf when attempting to recalibrate
- * more than 77 steps
- */
- /* go back to 0: */
- if (fd_cmd(fdcu, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
- /* a second being enough for full stroke seek*/
- DELAY(i == 0? 1000000: 300000);
+ for (i = 0; i < 2; i++) {
+ /*
+ * we must recalibrate twice, just in case the
+ * heads have been beyond cylinder 76, since most
+ * FDCs still barf when attempting to recalibrate
+ * more than 77 steps
+ */
+ /* go back to 0: */
+ if (fd_cmd(fdc, 2, NE7CMD_RECAL, fdsu, 0) == 0) {
+ /* a second being enough for full stroke seek*/
+ DELAY(i == 0 ? 1000000 : 300000);
- /* anything responding? */
- if (fd_sense_int(fdc, &st0, 0) == 0 &&
- (st0 & NE7_ST0_EC) == 0)
- break; /* already probed succesfully */
- }
+ /* anything responding? */
+ if (fd_sense_int(fdc, &st0, 0) == 0 &&
+ (st0 & NE7_ST0_EC) == 0)
+ break; /* already probed succesfully */
}
+ }
- set_motor(fdcu, fdsu, TURNOFF);
+ set_motor(fdc, fdsu, TURNOFF);
- if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
- continue;
+ if (st0 & NE7_ST0_EC) /* no track 0 -> no drive present */
+ return (ENXIO);
+#endif /* PC98 */
+
+ fd->track = FD_NO_TRACK;
+ fd->fdc = fdc;
+ fd->fdsu = fdsu;
+ fd->options = 0;
+ callout_handle_init(&fd->toffhandle);
+ callout_handle_init(&fd->tohandle);
+
+#ifdef PC98
+ switch (fdt) {
+ case FDT_12M:
+#ifdef EPSON_NRDISK
+ if (fdu == nrdu) {
+ device_set_desc(dev, "EPSON RAM DRIVE");
+ nrd_LED_off();
+ } else
+ device_set_desc(dev, "1M/640M FDD");
+#else
+ device_set_desc(dev, "1M/640M FDD");
+#endif
+ fd->type = FD_1200;
+ fd->pc98_trans = 0;
+ break;
+ case FDT_144M:
+ device_set_desc(dev, "1.44M FDD");
+ fd->type = FD_1200;
+ fd->pc98_trans = 0;
+ outb(0x4be, (fd->fdu << 5) | 0x10);
+ break;
+ default:
+ return (ENXIO);
+ }
+#else
+ switch (fdt) {
+ case RTCFDT_12M:
+ device_set_desc(dev, "1200-KB 5.25\" drive");
+ fd->type = FD_1200;
+ break;
+ case RTCFDT_144M | RTCFDT_144M_PRETENDED:
+ device_set_desc(dev, "config-pretended 1440-MB 3.5\" drive");
+ fdt = RTCFDT_144M;
+ fd->type = FD_1440;
+ case RTCFDT_144M:
+ device_set_desc(dev, "1440-KB 3.5\" drive");
+ fd->type = FD_1440;
+ break;
+ case RTCFDT_288M:
+ case RTCFDT_288M_1:
+ device_set_desc(dev, "2880-KB 3.5\" drive (in 1440-KB mode)");
+ fd->type = FD_1440;
+ break;
+ case RTCFDT_360K:
+ device_set_desc(dev, "360-KB 5.25\" drive");
+ fd->type = FD_360;
+ break;
+ case RTCFDT_720K:
+ printf("720-KB 3.5\" drive");
+ fd->type = FD_720;
+ break;
+ default:
+ return (ENXIO);
+ }
#endif
+ return (0);
+}
- fd->track = FD_NO_TRACK;
- fd->fdc = fdc;
- fd->fdsu = fdsu;
- fd->options = 0;
- callout_handle_init(&fd->toffhandle);
- callout_handle_init(&fd->tohandle);
- printf("fd%d: ", fdu);
-
- switch (fdt) {
+static int
+fd_attach(device_t dev)
+{
+ struct fd_data *fd;
+
+ fd = device_get_softc(dev);
+
+#ifdef DEVFS /* XXX bitrot */
+ mynor = fdu << 6;
+ fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK,
+ UID_ROOT, GID_OPERATOR, 0640,
+ "fd%d", fdu);
+ fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
+ UID_ROOT, GID_OPERATOR, 0640,
+ "rfd%d", fdu);
+ for (i = 1; i < 1 + NUMDENS; i++) {
+ /*
+ * XXX this and the lookup in Fdopen() should be
+ * data driven.
+ */
#ifdef PC98
+ switch (fd->type) {
case FDT_12M:
-#ifdef EPSON_NRDISK
- if (fdu == nrdu) {
- printf("EPSON RAM DRIVE\n");
- nrd_LED_off();
- }
- else printf("1M/640M FDD\n");
-#else /* !EPSON_NRDISK */
- printf("1M/640K FDD\n");
-#endif /* EPSON_NRDISK */
- fd->type = FD_1200;
- fd->pc98_trans = 0;
+ if (i != FD_1200 && i != FD_1232
+ && i != FD_720 && i != FD_640)
+ continue;
break;
case FDT_144M:
- printf("1.44M FDD\n");
- fd->type = FD_1200;
- fd->pc98_trans = 0;
- outb(0x4be, (fdu << 5) | 0x10);
+ if (i != FD_1200 && i != FD_1232
+ && i != FD_720 && i != FD_640
+ && i != FD_1440)
+ continue;
break;
+ }
#else
- case RTCFDT_12M:
- printf("1.2MB 5.25in\n");
- fd->type = FD_1200;
+ switch (fd->type) {
+ case FD_360:
+ if (i != FD_360)
+ continue;
break;
- case RTCFDT_144M | RTCFDT_144M_PRETENDED:
- printf("config-pretended ");
- fdt = RTCFDT_144M;
- /* fallthrough */
- case RTCFDT_144M:
- printf("1.44MB 3.5in\n");
- fd->type = FD_1440;
+ case FD_720:
+ if (i != FD_720 && i != FD_800 && i != FD_820)
+ continue;
break;
- case RTCFDT_288M:
- case RTCFDT_288M_1:
- printf("2.88MB 3.5in - 1.44MB mode\n");
- fd->type = FD_1440;
+ case FD_1200:
+ if (i != FD_360 && i != FD_720 && i != FD_800
+ && i != FD_820 && i != FD_1200
+ && i != FD_1440 && i != FD_1480)
+ continue;
break;
- case RTCFDT_360K:
- printf("360KB 5.25in\n");
- fd->type = FD_360;
+ case FD_1440:
+ if (i != FD_720 && i != FD_800 && i != FD_820
+ && i != FD_1200 && i != FD_1440
+ && i != FD_1480 && i != FD_1720)
+ continue;
break;
- case RTCFDT_720K:
- printf("720KB 3.5in\n");
- fd->type = FD_720;
- break;
-#endif
- default:
- printf("unknown\n");
- fd->type = NO_TYPE;
- continue;
}
-#ifdef DEVFS
- mynor = fdu << 6;
- fd->bdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640,
- "fd%d", fdu);
- fd->cdevs[0] = devfs_add_devswf(&fd_cdevsw, mynor, DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640,
- "rfd%d", fdu);
- for (i = 1; i < 1 + NUMDENS; i++) {
- /*
- * XXX this and the lookup in Fdopen() should be
- * data driven.
- */
-#ifdef PC98
- switch (fdt) {
- case FDT_12M:
- if (i != FD_1200 && i != FD_1232
- && i != FD_720 && i != FD_640)
- continue;
- break;
- case FDT_144M:
- if (i != FD_1200 && i != FD_1232
- && i != FD_720 && i != FD_640
- && i != FD_1440)
- continue;
- break;
- }
-#else
- switch (fd->type) {
- case FD_360:
- if (i != FD_360)
- continue;
- break;
- case FD_720:
- if (i != FD_720 && i != FD_800 && i != FD_820)
- continue;
- break;
- case FD_1200:
- if (i != FD_360 && i != FD_720 && i != FD_800
- && i != FD_820 && i != FD_1200
- && i != FD_1440 && i != FD_1480)
- continue;
- break;
- case FD_1440:
- if (i != FD_720 && i != FD_800 && i != FD_820
- && i != FD_1200 && i != FD_1440
- && i != FD_1480 && i != FD_1720)
- continue;
- break;
- }
#endif
#ifdef PC98
- if (i == FD_1232)
- typesize = fd_types[i - 1].size;
- else
- typesize = fd_types[i - 1].size / 2;
-#else
+ if (i == FD_1232)
+ typesize = fd_types[i - 1].size;
+ else
typesize = fd_types[i - 1].size / 2;
- /*
- * XXX all these conversions give bloated code and
- * confusing names.
- */
- if (typesize == 1476)
- typesize = 1480;
- if (typesize == 1722)
- typesize = 1720;
-#endif
- typemynor = mynor | i;
- fd->bdevs[i] =
- devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK,
- UID_ROOT, GID_OPERATOR, 0640,
- "fd%d.%d", fdu, typesize);
- fd->cdevs[i] =
- devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR,
- UID_ROOT, GID_OPERATOR, 0640,
- "rfd%d.%d", fdu, typesize);
- }
-
- for (i = 0; i < MAXPARTITIONS; i++) {
- fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0],
- "fd%d%c", fdu, 'a' + i);
- fd->cdevs[1 + NUMDENS + i] =
- devfs_makelink(fd->cdevs[0],
- "rfd%d%c", fdu, 'a' + i);
- }
-#endif /* DEVFS */
+#else
+ typesize = fd_types[i - 1].size / 2;
/*
- * Export the drive to the devstat interface.
+ * XXX all these conversions give bloated code and
+ * confusing names.
*/
- devstat_add_entry(&fd->device_stats, "fd",
- fdu, 512,
- DEVSTAT_NO_ORDERED_TAGS,
- DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER,
- DEVSTAT_PRIORITY_FD);
-
+ if (typesize == 1476)
+ typesize = 1480;
+ if (typesize == 1722)
+ typesize = 1720;
+#endif
+ typemynor = mynor | i;
+ fd->bdevs[i] =
+ devfs_add_devswf(&fd_cdevsw, typemynor, DV_BLK,
+ UID_ROOT, GID_OPERATOR, 0640,
+ "fd%d.%d", fdu, typesize);
+ fd->cdevs[i] =
+ devfs_add_devswf(&fd_cdevsw, typemynor, DV_CHR,
+ UID_ROOT, GID_OPERATOR, 0640,
+ "rfd%d.%d", fdu, typesize);
}
- return (1);
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ fd->bdevs[1 + NUMDENS + i] = devfs_makelink(fd->bdevs[0],
+ "fd%d%c", fdu, 'a' + i);
+ fd->cdevs[1 + NUMDENS + i] =
+ devfs_makelink(fd->cdevs[0],
+ "rfd%d%c", fdu, 'a' + i);
+ }
+#endif /* DEVFS */
+ /*
+ * Export the drive to the devstat interface.
+ */
+ devstat_add_entry(&fd->device_stats, device_get_name(dev),
+ device_get_unit(dev), 512, DEVSTAT_NO_ORDERED_TAGS,
+ DEVSTAT_TYPE_FLOPPY | DEVSTAT_TYPE_IF_OTHER,
+ DEVSTAT_PRIORITY_FD);
+ return (0);
}
-
-
#ifdef FDC_YE
/*
* this is a subset of fdattach() optimized for the Y-E Data
@@ -1307,9 +1377,9 @@ static int yeattach(struct isa_device *dev)
/* remember to not deselect the drive we're working on */
/****************************************************************************/
static void
-set_motor(fdcu_t fdcu, int fdsu, int turnon)
+set_motor(struct fdc_data *fdc, int fdsu, int turnon)
{
- int fdout = fdc_data[fdcu].fdout;
+ int fdout = fdc->fdout;
int needspecify = 0;
#ifdef PC98
@@ -1335,12 +1405,11 @@ set_motor(fdcu_t fdcu, int fdsu, int turnon)
}
#endif
- outb(fdc_data[fdcu].baseport+FDOUT, fdout);
- DELAY(10);
- fdc_data[fdcu].fdout = fdout;
+ outb(fdc->baseport+FDOUT, fdout);
+ fdc->fdout = fdout;
TRACE1("[0x%x->FDOUT]", fdout);
- if(needspecify) {
+ if (needspecify) {
/*
* XXX
* special case: since we have just woken up the FDC
@@ -1348,81 +1417,75 @@ set_motor(fdcu_t fdcu, int fdsu, int turnon)
* be accepted, and do not test for a timeout
*/
#ifdef PC98
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
+ (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
0);
#else
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
+ (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
0);
#endif
- if (fdc_data[fdcu].flags & FDC_HAS_FIFO)
- (void) enable_fifo(&fdc_data[fdcu]);
-
+ if (fdc->flags & FDC_HAS_FIFO)
+ (void) enable_fifo(fdc);
}
}
static void
-fd_turnoff(void *arg1)
+fd_turnoff(void *xfd)
{
- fdu_t fdu = (fdu_t)arg1;
int s;
- fd_p fd = fd_data + fdu;
+ fd_p fd = xfd;
- TRACE1("[fd%d: turnoff]", fdu);
+ TRACE1("[fd%d: turnoff]", fd->fdu);
/*
* Don't turn off the motor yet if the drive is active.
* XXX shouldn't even schedule turnoff until drive is inactive
* and nothing is queued on it.
*/
- if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fdu) {
- fd->toffhandle = timeout(fd_turnoff, arg1, 4 * hz);
+ if (fd->fdc->state != DEVIDLE && fd->fdc->fdu == fd->fdu) {
+ fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);
return;
}
s = splbio();
fd->flags &= ~FD_MOTOR;
- set_motor(fd->fdc->fdcu, fd->fdsu, TURNOFF);
+ set_motor(fd->fdc, fd->fdsu, TURNOFF);
splx(s);
}
static void
-fd_motor_on(void *arg1)
+fd_motor_on(void *xfd)
{
- fdu_t fdu = (fdu_t)arg1;
int s;
+ fd_p fd = xfd;
- fd_p fd = fd_data + fdu;
s = splbio();
fd->flags &= ~FD_MOTOR_WAIT;
if((fd->fdc->fd == fd) && (fd->fdc->state == MOTORWAIT))
{
- fdintr(fd->fdc->fdcu);
+ fdc_intr(fd->fdc);
}
splx(s);
}
static void
-fd_turnon(fdu_t fdu)
+fd_turnon(fd_p fd)
{
- fd_p fd = fd_data + fdu;
if(!(fd->flags & FD_MOTOR))
{
fd->flags |= (FD_MOTOR + FD_MOTOR_WAIT);
- set_motor(fd->fdc->fdcu, fd->fdsu, TURNON);
- timeout(fd_motor_on, (caddr_t)fdu, hz); /* in 1 sec its ok */
+ set_motor(fd->fdc, fd->fdsu, TURNON);
+ timeout(fd_motor_on, fd, hz); /* in 1 sec its ok */
}
}
static void
fdc_reset(fdc_p fdc)
{
- fdcu_t fdcu = fdc->fdcu;
-
/* Try a reset, keep motor on */
#ifdef PC98
- set_density(fdcu, 0);
+ set_density(fdc);
if (pc98_machine_type & M_EPSON_PC98)
outb(fdc->baseport + FDOUT, 0xe8);
else
@@ -1444,11 +1507,11 @@ fdc_reset(fdc_p fdc)
/* XXX after a reset, silently believe the FDC will accept commands */
#ifdef PC98
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
+ (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(4, 240), NE7_SPEC_2(2, 0),
0);
#else
- (void)fd_cmd(fdcu, 3, NE7CMD_SPECIFY,
+ (void)fd_cmd(fdc, 3, NE7CMD_SPECIFY,
NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
0);
#endif
@@ -1460,16 +1523,16 @@ fdc_reset(fdc_p fdc)
/* fdc in/out */
/****************************************************************************/
int
-in_fdc(fdcu_t fdcu)
+in_fdc(struct fdc_data *fdc)
{
- int baseport = fdc_data[fdcu].baseport;
+ int baseport = fdc->baseport;
int i, j = 100000;
while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM))
!= (NE7_DIO|NE7_RQM) && j-- > 0)
if (i == NE7_RQM)
- return fdc_err(fdcu, "ready for output in input\n");
+ return fdc_err(fdc, "ready for output in input\n");
if (j <= 0)
- return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0);
+ return fdc_err(fdc, bootverbose? "input ready timeout\n": 0);
#ifdef FDC_DEBUG
i = inb(baseport+FDDATA);
TRACE1("[FDDATA->0x%x]", (unsigned char)i);
@@ -1483,16 +1546,16 @@ in_fdc(fdcu_t fdcu)
* fd_in: Like in_fdc, but allows you to see if it worked.
*/
static int
-fd_in(fdcu_t fdcu, int *ptr)
+fd_in(struct fdc_data *fdc, int *ptr)
{
- int baseport = fdc_data[fdcu].baseport;
+ int baseport = fdc->baseport;
int i, j = 100000;
while ((i = inb(baseport+FDSTS) & (NE7_DIO|NE7_RQM))
!= (NE7_DIO|NE7_RQM) && j-- > 0)
if (i == NE7_RQM)
- return fdc_err(fdcu, "ready for output in input\n");
+ return fdc_err(fdc, "ready for output in input\n");
if (j <= 0)
- return fdc_err(fdcu, bootverbose? "input ready timeout\n": 0);
+ return fdc_err(fdc, bootverbose? "input ready timeout\n": 0);
#ifdef FDC_DEBUG
i = inb(baseport+FDDATA);
TRACE1("[FDDATA->0x%x]", (unsigned char)i);
@@ -1507,21 +1570,21 @@ fd_in(fdcu_t fdcu, int *ptr)
}
int
-out_fdc(fdcu_t fdcu, int x)
+out_fdc(struct fdc_data *fdc, int x)
{
- int baseport = fdc_data[fdcu].baseport;
+ int baseport = fdc->baseport;
int i;
/* Check that the direction bit is set */
i = 100000;
while ((inb(baseport+FDSTS) & NE7_DIO) && i-- > 0);
- if (i <= 0) return fdc_err(fdcu, "direction bit not set\n");
+ if (i <= 0) return fdc_err(fdc, "direction bit not set\n");
/* Check that the floppy controller is ready for a command */
i = 100000;
while ((inb(baseport+FDSTS) & NE7_RQM) == 0 && i-- > 0);
if (i <= 0)
- return fdc_err(fdcu, bootverbose? "output ready timeout\n": 0);
+ return fdc_err(fdc, bootverbose? "output ready timeout\n": 0);
/* Send the command and return */
outb(baseport+FDDATA, x);
@@ -1537,37 +1600,38 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
{
fdu_t fdu = FDUNIT(minor(dev));
int type = FDTYPE(minor(dev));
+ fd_p fd;
fdc_p fdc;
/* check bounds */
- if (fdu >= NFD)
- return(ENXIO);
- fdc = fd_data[fdu].fdc;
- if ((fdc == NULL) || (fd_data[fdu].type == NO_TYPE))
- return(ENXIO);
+ if ((fd = devclass_get_softc(fd_devclass, fdu)) == 0)
+ return (ENXIO);
+ fdc = fd->fdc;
+ if ((fdc == NULL) || (fd->type == NO_TYPE))
+ return (ENXIO);
if (type > NUMDENS)
- return(ENXIO);
+ return (ENXIO);
#ifdef PC98
if (pc98_fd_check_ready(fdu) == -1)
return(EIO);
#endif
if (type == 0)
- type = fd_data[fdu].type;
+ type = fd->type;
#ifndef PC98
else {
/*
* For each type of basic drive, make sure we are trying
* to open a type it can do,
*/
- if (type != fd_data[fdu].type) {
- switch (fd_data[fdu].type) {
+ if (type != fd->type) {
+ switch (fd->type) {
case FD_360:
- return(ENXIO);
+ return (ENXIO);
case FD_720:
if ( type != FD_820
&& type != FD_800
)
- return(ENXIO);
+ return (ENXIO);
break;
case FD_1200:
switch (type) {
@@ -1607,9 +1671,10 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
}
}
#endif
- fd_data[fdu].ft = fd_types + type - 1;
- fd_data[fdu].flags |= FD_OPEN;
-
+ fd->ft = fd_types + type - 1;
+ fd->flags |= FD_OPEN;
+ device_busy(fd->dev);
+ device_busy(fd->fdc->fdc_dev);
return 0;
}
@@ -1617,11 +1682,13 @@ int
fdclose(dev_t dev, int flags, int mode, struct proc *p)
{
fdu_t fdu = FDUNIT(minor(dev));
+ struct fd_data *fd;
- fd_data[fdu].flags &= ~FD_OPEN;
- fd_data[fdu].options &= ~FDOPT_NORETRY;
+ fd = devclass_get_softc(fd_devclass, fdu);
+ fd->flags &= ~FD_OPEN;
+ fd->options &= ~FDOPT_NORETRY;
- return(0);
+ return (0);
}
static int
@@ -1645,16 +1712,17 @@ fdstrategy(struct buf *bp)
{
unsigned nblocks, blknum, cando;
int s;
- fdcu_t fdcu;
fdu_t fdu;
fdc_p fdc;
fd_p fd;
size_t fdblk;
fdu = FDUNIT(minor(bp->b_dev));
- fd = &fd_data[fdu];
+ fd = devclass_get_softc(fd_devclass, fdu);
+ if (fd == 0)
+ panic("fdstrategy: buf for nonexistent device (%#lx, %#lx)",
+ (u_long)major(bp->b_dev), (u_long)minor(bp->b_dev));
fdc = fd->fdc;
- fdcu = fdc->fdcu;
#ifdef FDC_YE
if (fd->type == NO_TYPE) {
bp->b_error = ENXIO;
@@ -1669,7 +1737,7 @@ fdstrategy(struct buf *bp)
fdblk = 128 << (fd->ft->secsize);
if (!(bp->b_flags & B_FORMAT)) {
- if ((fdu >= NFD) || (bp->b_blkno < 0)) {
+ if (bp->b_blkno < 0) {
printf(
"fd%d: fdstrat: bad request blkno = %lu, bcount = %ld\n",
fdu, (u_long)bp->b_blkno, bp->b_bcount);
@@ -1699,14 +1767,6 @@ fdstrategy(struct buf *bp)
blknum = (unsigned) bp->b_blkno * DEV_BSIZE/fdblk;
nblocks = fd->ft->size;
bp->b_resid = 0;
-#ifdef PC98
-#define B_XXX2 0x8000000
- if (bp->b_flags & B_XXX2) {
- blknum *= 2;
- bp->b_blkno *= 2;
- bp->b_flags &= ~B_XXX2;
- }
-#endif
if (blknum + (bp->b_bcount / fdblk) > nblocks) {
if (blknum <= nblocks) {
cando = (nblocks - blknum) * fdblk;
@@ -1722,12 +1782,12 @@ fdstrategy(struct buf *bp)
bp->b_pblkno = bp->b_blkno;
s = splbio();
bufqdisksort(&fdc->head, bp);
- untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle); /* a good idea */
+ untimeout(fd_turnoff, fd, fd->toffhandle); /* a good idea */
/* Tell devstat we are starting on the transaction */
devstat_start_transaction(&fd->device_stats);
- fdstart(fdcu);
+ fdstart(fdc);
splx(s);
return;
@@ -1745,27 +1805,25 @@ bad:
* will pick up our work when the present work completes *
\***************************************************************/
static void
-fdstart(fdcu_t fdcu)
+fdstart(struct fdc_data *fdc)
{
int s;
s = splbio();
- if(fdc_data[fdcu].state == DEVIDLE)
+ if(fdc->state == DEVIDLE)
{
- fdintr(fdcu);
+ fdc_intr(fdc);
}
splx(s);
}
static void
-fd_iotimeout(void *arg1)
+fd_iotimeout(void *xfdc)
{
fdc_p fdc;
- fdcu_t fdcu;
int s;
- fdcu = (fdcu_t)arg1;
- fdc = fdc_data + fdcu;
+ fdc = xfdc;
TRACE1("fd%d[fd_iotimeout()]", fdc->fdu);
/*
@@ -1783,19 +1841,18 @@ fd_iotimeout(void *arg1)
fdc->status[0] = NE7_ST0_IC_IV;
fdc->flags &= ~FDC_STAT_VALID;
fdc->state = IOTIMEDOUT;
- fdintr(fdcu);
+ fdc_intr(fdc);
splx(s);
}
/* just ensure it has the right spl */
static void
-fd_pseudointr(void *arg1)
+fd_pseudointr(void *xfdc)
{
- fdcu_t fdcu = (fdcu_t)arg1;
int s;
s = splbio();
- fdintr(fdcu);
+ fdc_intr(xfdc);
splx(s);
}
@@ -1805,11 +1862,11 @@ fd_pseudointr(void *arg1)
* ALWAYS called at SPLBIO *
\***********************************************************************/
static void
-fdintr(fdcu_t fdcu)
+fdc_intr(void *xfdc)
{
- fdc_p fdc = fdc_data + fdcu;
- while(fdstate(fdcu, fdc))
- ;
+ fdc_p fdc = xfdc;
+ while(fdstate(fdc))
+ ;
}
#ifdef FDC_YE
@@ -1849,7 +1906,7 @@ static int fdcpio(fdcu_t fdcu, long flags, caddr_t addr, u_int count)
* if it returns a non zero value, it should be called again immediatly *
\***********************************************************************/
static int
-fdstate(fdcu_t fdcu, fdc_p fdc)
+fdstate(fdc_p fdc)
{
int read, format, head, i, sec = 0, sectrac, st0, cyl, st3;
unsigned blknum = 0, b_cylinder = 0;
@@ -1873,26 +1930,25 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
* Force into the IDLE state, *
\***********************************************/
fdc->state = DEVIDLE;
- if(fdc->fd)
- {
- printf("fd%d: unexpected valid fd pointer\n",
- fdc->fdu);
+ if (fdc->fd) {
+ device_print_prettyname(fdc->fdc_dev);
+ printf("unexpected valid fd pointer\n");
fdc->fd = (fd_p) 0;
fdc->fdu = -1;
}
- TRACE1("[fdc%d IDLE]", fdcu);
- return(0);
+ TRACE1("[fdc%d IDLE]", fdc->fdcu);
+ return (0);
}
fdu = FDUNIT(minor(bp->b_dev));
- fd = fd_data + fdu;
+ fd = devclass_get_softc(fd_devclass, fdu);
fdblk = 128 << fd->ft->secsize;
- if (fdc->fd && (fd != fdc->fd))
- {
- printf("fd%d: confused fd pointers\n", fdu);
+ if (fdc->fd && (fd != fdc->fd)) {
+ device_print_prettyname(fd->dev);
+ printf("confused fd pointers\n");
}
read = bp->b_flags & B_READ;
format = bp->b_flags & B_FORMAT;
- if(format) {
+ if (format) {
finfo = (struct fd_formb *)bp->b_data;
fd->skip = (char *)&(finfo->fd_formb_cylno(0))
- (char *)finfo;
@@ -1905,8 +1961,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
TRACE1("fd%d", fdu);
TRACE1("[%s]", fdstates[fdc->state]);
TRACE1("(0x%x)", fd->flags);
- untimeout(fd_turnoff, (caddr_t)fdu, fd->toffhandle);
- fd->toffhandle = timeout(fd_turnoff, (caddr_t)fdu, 4 * hz);
+ untimeout(fd_turnoff, fd, fd->toffhandle);
+ fd->toffhandle = timeout(fd_turnoff, fd, 4 * hz);
switch (fdc->state)
{
case DEVIDLE:
@@ -1919,7 +1975,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
pc98_trans = fd->ft->trans;
if (pc98_trans_prev != pc98_trans) {
int i;
- set_density(fdcu, fdu);
+ set_density(fdc);
for (i = 0; i < 10; i++) {
outb(0x5f, 0);
outb(0x5f, 0);
@@ -1943,10 +1999,9 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
* If the next drive has a motor startup pending, then *
* it will start up in its own good time *
\*******************************************************/
- if(fd->flags & FD_MOTOR_WAIT)
- {
+ if(fd->flags & FD_MOTOR_WAIT) {
fdc->state = MOTORWAIT;
- return(0); /* come back later */
+ return (0); /* come back later */
}
/*******************************************************\
* Maybe if it's not starting, it SHOULD be starting *
@@ -1968,12 +2023,12 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
if (!(fd->flags & FD_MOTOR))
{
fdc->state = MOTORWAIT;
- fd_turnon(fdu);
- return(0);
+ fd_turnon(fd);
+ return (0);
}
else /* at least make sure we are selected */
{
- set_motor(fdcu, fd->fdsu, TURNON);
+ set_motor(fdc, fd->fdsu, TURNON);
}
#endif
if (fdc->flags & FDC_NEEDS_RESET) {
@@ -1991,7 +2046,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
#ifdef PC98
pc98_fd_check_ready(fdu);
#endif
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK,
+ if (fd_cmd(fdc, 3, NE7CMD_SEEK,
fd->fdsu, b_cylinder * fd->ft->steptrac,
0))
{
@@ -2000,20 +2055,19 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
* the FDC went off to the Saints...
*/
fdc->retry = 6; /* try a reset */
- return(retrier(fdcu));
+ return(retrier(fdc));
}
fd->track = FD_NO_TRACK;
fdc->state = SEEKWAIT;
return(0); /* will return later */
case SEEKWAIT:
/* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, hz / 16);
+ timeout(fd_pseudointr, fdc, hz / 16);
fdc->state = SEEKCOMPLETE;
return(0); /* will return later */
case SEEKCOMPLETE : /* SEEK DONE, START DMA */
/* Make sure seek really happened*/
- if(fd->track == FD_NO_TRACK)
- {
+ if(fd->track == FD_NO_TRACK) {
int descyl = b_cylinder * fd->ft->steptrac;
do {
/*
@@ -2045,8 +2099,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
return 0; /* hope for a real intr */
} while ((st0 & NE7_ST0_IC) == NE7_ST0_IC_RC);
- if (0 == descyl)
- {
+ if (0 == descyl) {
int failed = 0;
/*
* seek to cyl 0 requested; make sure we are
@@ -2064,25 +2117,23 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
failed = 1;
}
- if (failed)
- {
+ if (failed) {
if(fdc->retry < 3)
fdc->retry = 3;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
}
#ifdef EPSON_NRDISK
if (fdu == nrdu) cyl = descyl;
#endif
- if (cyl != descyl)
- {
+ if (cyl != descyl) {
printf(
"fd%d: Seek to cyl %d failed; am at cyl %d (ST0 = 0x%x)\n",
fdu, descyl, cyl, st0);
if (fdc->retry < 3)
fdc->retry = 3;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
}
@@ -2100,6 +2151,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
head = sec / sectrac;
sec = sec % sectrac + 1;
fd->hddrv = ((head&1)<<2)+fdu;
+
if(format || !read)
{
/* make sure the drive is writable */
@@ -2110,7 +2162,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
format ? bp->b_bcount : fdblk,
fdc->dmachan);
fdc->retry = 6; /* reset the beast */
- return(retrier(fdcu));
+ return (retrier(fdc));
}
if(st3 & NE7_ST3_WP)
{
@@ -2133,8 +2185,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
}
}
- if(format)
- {
+ if (format) {
#ifdef FDC_YE
if (fdc->flags & FDC_PCMCIA)
(void)fdcpio(fdcu,bp->b_flags,
@@ -2142,25 +2193,19 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
bp->b_bcount);
#endif
/* formatting */
- if(fd_cmd(fdcu, 6,
- NE7CMD_FORMAT,
- head << 2 | fdu,
+ if(fd_cmd(fdc, 6, NE7CMD_FORMAT, head << 2 | fdu,
finfo->fd_formb_secshift,
finfo->fd_formb_nsecs,
finfo->fd_formb_gaplen,
- finfo->fd_formb_fillbyte,
- 0))
- {
+ finfo->fd_formb_fillbyte, 0)) {
/* controller fell over */
isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
format ? bp->b_bcount : fdblk,
fdc->dmachan);
fdc->retry = 6;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
- }
- else
- {
+ } else {
#ifdef FDC_YE
if (fdc->flags & FDC_PCMCIA) {
/*
@@ -2179,7 +2224,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdblk);
}
#endif
- if (fd_cmd(fdcu, 9,
+ if (fd_cmd(fdc, 9,
(read ? NE7CMD_READ : NE7CMD_WRITE),
head << 2 | fdu, /* head & unit */
fd->track, /* track */
@@ -2189,14 +2234,13 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
sectrac, /* sectors/track */
fd->ft->gap, /* gap size */
fd->ft->datalen, /* data length */
- 0))
- {
+ 0)) {
/* the beast is sleeping again */
isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
format ? bp->b_bcount : fdblk,
fdc->dmachan);
fdc->retry = 6;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
}
#ifdef FDC_YE
@@ -2218,8 +2262,8 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
*/
#endif
fdc->state = IOCOMPLETE;
- fd->tohandle = timeout(fd_iotimeout, (caddr_t)fdcu, hz);
- return(0); /* will return later */
+ fd->tohandle = timeout(fd_iotimeout, fdc, hz);
+ return (0); /* will return later */
#ifdef EPSON_NRDISK
}
else {
@@ -2263,19 +2307,18 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
case IOCOMPLETE: /* IO DONE, post-analyze */
#ifdef EPSON_NRDISK
if (fdu != nrdu)
- untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle);
+ untimeout(fd_iotimeout, fdc, fd->tohandle);
#else
- untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle);
+ untimeout(fd_iotimeout, fdc, fd->tohandle);
#endif
- if (fd_read_status(fdc, fd->fdsu))
- {
+ if (fd_read_status(fdc, fd->fdsu)) {
isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
format ? bp->b_bcount : fdblk,
fdc->dmachan);
if (fdc->retry < 6)
fdc->retry = 6; /* force a reset */
- return retrier(fdcu);
+ return (retrier(fdc));
}
fdc->state = IOTIMEDOUT;
@@ -2295,8 +2338,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
}
else nrd_LED_off();
#endif /* EPSON_NRDISK */
- if (fdc->status[0] & NE7_ST0_IC)
- {
+ if (fdc->status[0] & NE7_ST0_IC) {
if ((fdc->status[0] & NE7_ST0_IC) == NE7_ST0_IC_AT
&& fdc->status[1] & NE7_ST1_OR) {
/*
@@ -2316,17 +2358,14 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
&& fdc->status[2] & NE7_ST2_WC
&& fdc->retry < 3)
fdc->retry = 3; /* force recalibrate */
- return(retrier(fdcu));
+ return (retrier(fdc));
}
/* All OK */
fd->skip += fdblk;
- if (!format && fd->skip < bp->b_bcount - bp->b_resid)
- {
+ if (!format && fd->skip < bp->b_bcount - bp->b_resid) {
/* set up next transfer */
fdc->state = DOSEEK;
- }
- else
- {
+ } else {
/* ALL DONE */
fd->skip = 0;
fdc->bp = NULL;
@@ -2341,7 +2380,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdc->fdu = -1;
fdc->state = FINDWORK;
}
- return(1);
+ return (1);
case RESETCTLR:
fdc_reset(fdc);
fdc->retry++;
@@ -2360,21 +2399,18 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
#ifdef PC98
pc98_fd_check_ready(fdu);
#endif
- if(fd_cmd(fdcu,
- 2, NE7CMD_RECAL, fdu,
- 0)) /* Recalibrate Function */
- {
+ if(fd_cmd(fdc, 2, NE7CMD_RECAL, fdu, 0)) {
/* arrgl */
fdc->retry = 6;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
fdc->state = RECALWAIT;
- return(0); /* will return later */
+ return (0); /* will return later */
case RECALWAIT:
/* allow heads to settle */
- timeout(fd_pseudointr, (caddr_t)fdcu, hz / 8);
+ timeout(fd_pseudointr, fdc, hz / 8);
fdc->state = RECALCOMPLETE;
- return(0); /* will return later */
+ return (0); /* will return later */
case RECALCOMPLETE:
do {
/*
@@ -2406,16 +2442,16 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
printf("fd%d: recal failed ST0 %b cyl %d\n",
fdu, st0, NE7_ST0BITS, cyl);
if(fdc->retry < 3) fdc->retry = 3;
- return(retrier(fdcu));
+ return (retrier(fdc));
}
fd->track = 0;
/* Seek (probably) necessary */
fdc->state = DOSEEK;
- return(1); /* will return immediatly */
+ return (1); /* will return immediatly */
case MOTORWAIT:
if(fd->flags & FD_MOTOR_WAIT)
{
- return(0); /* time's not up yet */
+ return (0); /* time's not up yet */
}
if (fdc->flags & FDC_NEEDS_RESET) {
fdc->state = RESETCTLR;
@@ -2428,9 +2464,10 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
*/
fdc->state = STARTRECAL;
}
- return(1); /* will return immediatly */
+ return (1); /* will return immediatly */
default:
- printf("fdc%d: Unexpected FD int->", fdcu);
+ device_print_prettyname(fdc->fdc_dev);
+ printf("unexpected FD int->");
if (fd_read_status(fdc, fd->fdsu) == 0)
printf("FDC status :%x %x %x %x %x %x %x ",
fdc->status[0],
@@ -2445,28 +2482,31 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
if (fd_sense_int(fdc, &st0, &cyl) != 0)
{
printf("[controller is dead now]\n");
- return(0);
+ return (0);
}
printf("ST0 = %x, PCN = %x\n", st0, cyl);
- return(0);
+ return (0);
}
/*XXX confusing: some branches return immediately, others end up here*/
- return(1); /* Come back immediatly to new state */
+ return (1); /* Come back immediatly to new state */
}
static int
-retrier(fdcu)
- fdcu_t fdcu;
+retrier(struct fdc_data *fdc)
{
- fdc_p fdc = fdc_data + fdcu;
register struct buf *bp;
+ struct fd_data *fd;
+ int fdu;
bp = fdc->bp;
- if(fd_data[FDUNIT(minor(bp->b_dev))].options & FDOPT_NORETRY)
+ /* XXX shouldn't this be cached somewhere? */
+ fdu = FDUNIT(minor(bp->b_dev));
+ fd = devclass_get_softc(fd_devclass, fdu);
+ if (fd->options & FDOPT_NORETRY)
goto fail;
- switch(fdc->retry)
- {
+
+ switch (fdc->retry) {
case 0: case 1: case 2:
fdc->state = SEEKCOMPLETE;
break;
@@ -2519,10 +2559,10 @@ retrier(fdcu)
fdc->flags |= FDC_NEEDS_RESET;
fdc->fd = (fd_p) 0;
fdc->fdu = -1;
- return(1);
+ return (1);
}
fdc->retry++;
- return(1);
+ return (1);
}
static int
@@ -2539,7 +2579,7 @@ fdformat(dev, finfo, p)
size_t fdblk;
fdu = FDUNIT(minor(dev));
- fd = &fd_data[fdu];
+ fd = devclass_get_softc(fd_devclass, fdu);
fdblk = 128 << fd->ft->secsize;
/* set up a buffer header for fdstrategy() */
@@ -2570,20 +2610,19 @@ fdformat(dev, finfo, p)
/* ...and wait for it to complete */
s = splbio();
- while(!(bp->b_flags & B_DONE))
- {
+ while(!(bp->b_flags & B_DONE)) {
rv = tsleep((caddr_t)bp, PRIBIO, "fdform", 20 * hz);
- if(rv == EWOULDBLOCK)
+ if (rv == EWOULDBLOCK)
break;
}
splx(s);
- if(rv == EWOULDBLOCK) {
+ if (rv == EWOULDBLOCK) {
/* timed out */
rv = EIO;
biodone(bp);
}
- if(bp->b_flags & B_ERROR)
+ if (bp->b_flags & B_ERROR)
rv = bp->b_error;
/*
* allow the process to be swapped
@@ -2606,7 +2645,7 @@ fdioctl(dev, cmd, addr, flag, p)
struct proc *p;
{
fdu_t fdu = FDUNIT(minor(dev));
- fd_p fd = &fd_data[fdu];
+ fd_p fd = devclass_get_softc(fd_devclass, fdu);
size_t fdblk;
struct fd_type *fdt;
@@ -2617,15 +2656,14 @@ fdioctl(dev, cmd, addr, flag, p)
fdblk = 128 << fd->ft->secsize;
#ifdef PC98
- pc98_fd_check_ready(fdu);
+ pc98_fd_check_ready(fdu);
#endif
- switch (cmd)
- {
+ switch (cmd) {
case DIOCGDINFO:
bzero(buffer, sizeof (buffer));
dl = (struct disklabel *)buffer;
dl->d_secsize = fdblk;
- fdt = fd_data[FDUNIT(minor(dev))].ft;
+ fdt = fd->ft;
dl->d_secpercyl = fdt->size / fdt->tracks;
dl->d_type = DTYPE_FLOPPY;
@@ -2649,8 +2687,7 @@ fdioctl(dev, cmd, addr, flag, p)
break;
case DIOCWDINFO:
- if ((flag & FWRITE) == 0)
- {
+ if ((flag & FWRITE) == 0) {
error = EBADF;
break;
}
@@ -2665,9 +2702,9 @@ fdioctl(dev, cmd, addr, flag, p)
(struct disklabel *)buffer);
break;
case FD_FORM:
- if((flag & FWRITE) == 0)
+ if ((flag & FWRITE) == 0)
error = EBADF; /* must be opened for writing */
- else if(((struct fd_formb *)addr)->format_version !=
+ else if (((struct fd_formb *)addr)->format_version !=
FD_FORMAT_VERSION)
error = EINVAL; /* wrong version of formatting prog */
else
@@ -2680,7 +2717,7 @@ fdioctl(dev, cmd, addr, flag, p)
case FD_STYPE: /* set drive type */
/* this is considered harmful; only allow for superuser */
- if(suser(p->p_ucred, &p->p_acflag) != 0)
+ if (suser(p->p_ucred, &p->p_acflag) != 0)
return EPERM;
*fd->ft = *(struct fd_type *)addr;
break;
@@ -2700,22 +2737,62 @@ fdioctl(dev, cmd, addr, flag, p)
return (error);
}
+static device_method_t fdc_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, fdc_probe),
+ DEVMETHOD(device_attach, fdc_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),
-static fd_devsw_installed = 0;
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, fdc_print_child),
+ /* Our children never use any other bus interface methods. */
-static void fd_drvinit(void *notused )
-{
+ { 0, 0 }
+};
- if( ! fd_devsw_installed ) {
- cdevsw_add_generic(BDEV_MAJOR,CDEV_MAJOR, &fd_cdevsw);
- fd_devsw_installed = 1;
- }
-}
+static driver_t fdc_driver = {
+ "fdc",
+ fdc_methods,
+ DRIVER_TYPE_BIO,
+ sizeof(struct fdc_data)
+};
-SYSINIT(fddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,fd_drvinit,NULL)
+DRIVER_MODULE(fdc, isa, fdc_driver, fdc_devclass, 0, 0);
+static device_method_t fd_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, fd_probe),
+ DEVMETHOD(device_attach, fd_attach),
+ DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend), /* XXX */
+ DEVMETHOD(device_resume, bus_generic_resume), /* XXX */
-#endif
+ { 0, 0 }
+};
+
+static driver_t fd_driver = {
+ "fd",
+ fd_methods,
+ DRIVER_TYPE_BIO,
+ sizeof(struct fd_data)
+};
+
+static struct cdevsw fd_cdevsw = {
+ Fdopen, fdclose, fdread, fdwrite,
+ fdioctl, nostop, nullreset, nodevtotty,
+ seltrue, nommap, fdstrategy, "fd",
+ NULL, -1, nodump, nopsize,
+ D_DISK, 0, -1
+};
+
+BDEV_DRIVER_MODULE(fd, fdc, fd_driver, fd_devclass, BDEV_MAJOR, CDEV_MAJOR,
+ fd_cdevsw, 0, 0);
+
+#endif /* NFDC > 0 */
/*
* Hello emacs, these are the
diff --git a/sys/pc98/pc98/if_ed.c b/sys/pc98/pc98/if_ed.c
index b71f68e..4358562 100644
--- a/sys/pc98/pc98/if_ed.c
+++ b/sys/pc98/pc98/if_ed.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_ed.c,v 1.60 1999/01/28 09:19:16 kato Exp $
+ * $Id: if_ed.c,v 1.61 1999/03/19 16:01:34 kato Exp $
*/
/*
@@ -4300,7 +4300,6 @@ static void
edpnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
{
struct pnp_cinfo d;
- struct isa_device *dvp;
if (dev->id_unit >= NEDTOT)
return;
@@ -4321,9 +4320,7 @@ edpnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
if (dev->id_driver == NULL) {
dev->id_driver = &eddriver;
- dvp = find_isadev(isa_devtab_net, &eddriver, 0);
- if (dvp != NULL)
- dev->id_id = dvp->id_id;
+ dev->id_id = isa_compat_nextid();
}
if ((dev->id_alive = ed_probe(dev)) != 0)
diff --git a/sys/pc98/pc98/isa_dma.c b/sys/pc98/pc98/isa_dma.c
new file mode 100644
index 0000000..6599b05
--- /dev/null
+++ b/sys/pc98/pc98/isa_dma.c
@@ -0,0 +1,560 @@
+/*-
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)isa.c 7.2 (Berkeley) 5/13/91
+ * $Id: isa_dma.c,v 1.1 1999/04/16 21:22:24 peter Exp $
+ */
+
+/*
+ * 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()
+ */
+
+#ifdef PC98
+#include "opt_pc98.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <machine/ipl.h>
+#include <machine/md_var.h>
+#ifdef APIC_IO
+#include <machine/smp.h>
+#endif /* APIC_IO */
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <i386/isa/isa_device.h>
+#include <i386/isa/intr_machdep.h>
+#ifdef PC98
+#include <pc98/pc98/pc98.h>
+#else
+#include <i386/isa/isa.h>
+#endif
+#include <i386/isa/ic/i8237.h>
+
+#include <sys/interrupt.h>
+
+#include "pnp.h"
+#if NPNP > 0
+#include <i386/isa/pnp.h>
+#endif
+
+/*
+** Register definitions for DMA controller 1 (channels 0..3):
+*/
+#ifdef PC98
+#define DMA1_CHN(c) (IO_DMA + (4*(c))) /* addr reg for channel c */
+#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 */
+#else
+#define DMA1_CHN(c) (IO_DMA1 + 1*(2*(c))) /* addr reg for channel c */
+#define DMA1_SMSK (IO_DMA1 + 1*10) /* single mask register */
+#define DMA1_MODE (IO_DMA1 + 1*11) /* mode register */
+#define DMA1_FFC (IO_DMA1 + 1*12) /* clear first/last FF */
+#endif
+
+/*
+** Register definitions for DMA controller 2 (channels 4..7):
+*/
+#define DMA2_CHN(c) (IO_DMA2 + 2*(2*(c))) /* addr reg for channel c */
+#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */
+#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */
+#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */
+
+static int isa_dmarangecheck __P((caddr_t va, u_int length, int chan));
+
+#ifdef PC98
+static caddr_t dma_bouncebuf[4];
+static u_int dma_bouncebufsize[4];
+#else
+static caddr_t dma_bouncebuf[8];
+static u_int dma_bouncebufsize[8];
+#endif
+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;
+
+#ifdef PC98
+#define VALID_DMA_MASK (3)
+#else
+#define VALID_DMA_MASK (7)
+#endif
+
+/* high byte of address is stored in this port for i-th dma channel */
+#ifdef PC98
+static int dmapageport[8] = { 0x27, 0x21, 0x23, 0x25 };
+#else
+static int dmapageport[8] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
+#endif
+
+/*
+ * Setup a DMA channel's bounce buffer.
+ */
+void
+isa_dmainit(chan, bouncebufsize)
+ int chan;
+ u_int bouncebufsize;
+{
+ void *buf;
+
+#ifdef DIAGNOSTIC
+ if (chan & ~VALID_DMA_MASK)
+ panic("isa_dmainit: channel out of range");
+
+ if (dma_bouncebuf[chan] != NULL)
+ panic("isa_dmainit: impossible request");
+#endif
+
+ dma_bouncebufsize[chan] = bouncebufsize;
+
+ /* Try malloc() first. It works better if it works. */
+ buf = malloc(bouncebufsize, M_DEVBUF, M_NOWAIT);
+ if (buf != NULL) {
+ if (isa_dmarangecheck(buf, bouncebufsize, chan) == 0) {
+ dma_bouncebuf[chan] = buf;
+ return;
+ }
+ free(buf, M_DEVBUF);
+ }
+ buf = contigmalloc(bouncebufsize, M_DEVBUF, M_NOWAIT, 0ul, 0xfffffful,
+ 1ul, chan & 4 ? 0x20000ul : 0x10000ul);
+ if (buf == NULL)
+ printf("isa_dmainit(%d, %d) failed\n", chan, bouncebufsize);
+ else
+ dma_bouncebuf[chan] = buf;
+}
+
+/*
+ * 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
+
+ if (dma_inuse & (1 << chan)) {
+ printf("isa_dma_acquire: channel %d already in use\n", chan);
+ return (EBUSY);
+ }
+ dma_inuse |= (1 << chan);
+ dma_auto_mode &= ~(1 << chan);
+
+ 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");
+
+ if ((dma_inuse & (1 << chan)) == 0)
+ printf("isa_dma_release: channel %d not in use\n", chan);
+#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);
+}
+
+#ifndef PC98
+/*
+ * isa_dmacascade(): program 8237 DMA controller channel to accept
+ * external dma control by a board.
+ */
+void
+isa_dmacascade(chan)
+ int chan;
+{
+#ifdef DIAGNOSTIC
+ if (chan & ~VALID_DMA_MASK)
+ panic("isa_dmacascade: channel out of range");
+#endif
+
+ /* set dma channel mode, and set dma channel mode */
+ if ((chan & 4) == 0) {
+ outb(DMA1_MODE, DMA37MD_CASCADE | chan);
+ outb(DMA1_SMSK, chan);
+ } else {
+ outb(DMA2_MODE, DMA37MD_CASCADE | (chan & 3));
+ outb(DMA2_SMSK, chan & 3);
+ }
+}
+#endif
+
+/*
+ * 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_offset_t phys;
+ int waport;
+ caddr_t newaddr;
+
+#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");
+
+ if ((dma_inuse & (1 << chan)) == 0)
+ printf("isa_dmastart: channel %d not acquired\n", chan);
+#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 (isa_dmarangecheck(addr, nbytes, chan)) {
+ 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 & B_READ))
+ bcopy(addr, newaddr, nbytes);
+ addr = newaddr;
+ }
+
+ /* translate to physical */
+ phys = pmap_extract(pmap_kernel(), (vm_offset_t)addr);
+
+ if (flags & B_RAW) {
+ dma_auto_mode |= (1 << chan);
+ } else {
+ dma_auto_mode &= ~(1 << chan);
+ }
+
+#ifndef PC98
+ if ((chan & 4) == 0) {
+ /*
+ * Program one of DMA channels 0..3. These are
+ * byte mode channels.
+ */
+#endif
+ /* set dma channel mode, and reset address ff */
+
+ /* If B_RAW flag is set, then use autoinitialise mode */
+ if (flags & B_RAW) {
+ if (flags & B_READ)
+ outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_WRITE|chan);
+ else
+ outb(DMA1_MODE, DMA37MD_AUTO|DMA37MD_READ|chan);
+ }
+ else
+ if (flags & B_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 + 1, --nbytes);
+ outb(waport + 1, nbytes>>8);
+
+ /* unmask channel */
+ outb(DMA1_SMSK, chan);
+#ifndef PC98
+ } else {
+ /*
+ * Program one of DMA channels 4..7. These are
+ * word mode channels.
+ */
+ /* set dma channel mode, and reset address ff */
+
+ /* If B_RAW flag is set, then use autoinitialise mode */
+ if (flags & B_RAW) {
+ if (flags & B_READ)
+ outb(DMA2_MODE, DMA37MD_AUTO|DMA37MD_WRITE|(chan&3));
+ else
+ outb(DMA2_MODE, DMA37MD_AUTO|DMA37MD_READ|(chan&3));
+ }
+ else
+ if (flags & B_READ)
+ outb(DMA2_MODE, DMA37MD_SINGLE|DMA37MD_WRITE|(chan&3));
+ else
+ outb(DMA2_MODE, DMA37MD_SINGLE|DMA37MD_READ|(chan&3));
+ outb(DMA2_FFC, 0);
+
+ /* send start address */
+ waport = DMA2_CHN(chan - 4);
+ outb(waport, phys>>1);
+ outb(waport, phys>>9);
+ outb(dmapageport[chan], phys>>16);
+
+ /* send count */
+ nbytes >>= 1;
+ outb(waport + 2, --nbytes);
+ outb(waport + 2, nbytes>>8);
+
+ /* unmask channel */
+ outb(DMA2_SMSK, chan & 3);
+ }
+#endif
+}
+
+void
+isa_dmadone(int flags, caddr_t addr, int nbytes, int chan)
+{
+#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
+
+ if (((dma_busy & (1 << chan)) == 0) &&
+ (dma_auto_mode & (1 << chan)) == 0 )
+ printf("isa_dmadone: channel %d not busy\n", chan);
+
+#ifdef PC98
+ if ((dma_auto_mode & (1 << chan)) == 0)
+ outb(DMA1_SMSK, (chan & 3) | 4);
+#else
+ if ((dma_auto_mode & (1 << chan)) == 0)
+ outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
+#endif
+
+ if (dma_bounced & (1 << chan)) {
+ /* copy bounce buffer on read */
+ if (flags & B_READ)
+ bcopy(dma_bouncebuf[chan], addr, nbytes);
+
+ dma_bounced &= ~(1 << chan);
+ }
+ dma_busy &= ~(1 << chan);
+}
+
+/*
+ * 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_offset_t phys, priorpage = 0, 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(pmap_kernel(), (vm_offset_t)va));
+#ifdef EPSON_BOUNCEDMA
+#define ISARAM_END 0xf00000
+#else
+#define ISARAM_END RAM_END
+#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.
+ *
+ */
+int
+isa_dmastatus(int chan)
+{
+ u_long cnt = 0;
+ int ffport, waport;
+ u_long low1, high1, low2, high2;
+
+ /* 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 ;
+ }
+#ifdef PC98
+ ffport = DMA1_FFC;
+ waport = DMA1_CHN(chan) + 2;
+#else
+ if (chan < 4) { /* low DMA controller */
+ ffport = DMA1_FFC;
+ waport = DMA1_CHN(chan) + 1;
+ } else { /* high DMA controller */
+ ffport = DMA2_FFC;
+ waport = DMA2_CHN(chan - 4) + 2;
+ }
+#endif
+
+ 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);
+}
+
+/*
+ * Stop a DMA transfer currently in progress.
+ */
+int
+isa_dmastop(int chan)
+{
+ 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);
+ return -2 ;
+ }
+
+ if ((chan & 4) == 0) {
+ outb(DMA1_SMSK, (chan & 3) | 4 /* disable mask */);
+ } else {
+#ifndef PC98
+ outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
+#endif
+ }
+ return(isa_dmastatus(chan));
+}
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 812c577..61950da 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.110 1999/03/06 09:43:01 kato Exp $
+ * $Id: machdep.c,v 1.111 1999/04/03 22:20:02 jdp Exp $
*/
#include "apm.h"
@@ -71,6 +71,7 @@
#include <sys/sysent.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
+#include <sys/bus.h>
#ifdef SYSVSHM
#include <sys/shm.h>
@@ -125,7 +126,9 @@
#include <machine/perfmon.h>
#endif
+#ifdef OLD_BUS_ARCH
#include <i386/isa/isa_device.h>
+#endif
#include <i386/isa/intr_machdep.h>
#ifdef PC98
#include <pc98/pc98/pc98_machdep.h>
@@ -153,7 +156,7 @@ SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL)
static MALLOC_DEFINE(M_MBUF, "mbuf", "mbuf");
#ifdef PC98
-int need_pre_dma_flush; /* If 1, use wbinvd befor DMA transfer. */
+int need_pre_dma_flush; /* If 1, use wbinvd befor DMA transfer. */
int need_post_dma_flush; /* If 1, use invd after DMA transfer. */
#endif
@@ -169,9 +172,9 @@ SYSCTL_INT(_debug, OID_AUTO, tlb_flush_count,
#endif
#ifdef PC98
-int ispc98 = 1;
+static int ispc98 = 1;
#else
-int ispc98 = 0;
+static int ispc98 = 0;
#endif
SYSCTL_INT(_machdep, OID_AUTO, ispc98, CTLFLAG_RD, &ispc98, 0, "");
@@ -850,6 +853,9 @@ setregs(p, entry, stack, ps_strings)
regs->tf_es = _udatasel;
regs->tf_cs = _ucodesel;
+ /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */
+ regs->tf_ebx = ps_strings;
+
/* reset %fs and %gs as well */
pcb->pcb_fs = _udatasel;
pcb->pcb_gs = _udatasel;
@@ -1174,8 +1180,10 @@ init386(first)
unsigned biosbasemem, biosextmem;
struct gate_descriptor *gdp;
int gsel_tss;
+#if NNPX > 0
+ int msize;
+#endif
- struct isa_device *idp;
#ifndef SMP
/* table descriptors - used to load tables by microp */
struct region_descriptor r_gdt, r_idt;
@@ -1478,10 +1486,11 @@ init386(first)
#endif
#if NNPX > 0
- idp = find_isadev(isa_devtab_null, &npxdriver, 0);
- if (idp != NULL && idp->id_msize != 0) {
- Maxmem = idp->id_msize / 4;
- speculative_mprobe = FALSE;
+ if (resource_int_value("npx", 0, "msize", &msize) == 0) {
+ if (msize != 0) {
+ Maxmem = msize / 4;
+ speculative_mprobe = FALSE;
+ }
}
#endif
diff --git a/sys/pc98/pc98/npx.c b/sys/pc98/pc98/npx.c
index a26ff4b..c17b50a 100644
--- a/sys/pc98/pc98/npx.c
+++ b/sys/pc98/pc98/npx.c
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
- * $Id: npx.c,v 1.42 1999/01/16 11:41:18 kato Exp $
+ * $Id: npx.c,v 1.43 1999/04/01 13:41:40 kato Exp $
*/
#include "npx.h"
@@ -44,10 +44,14 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
#ifdef NPX_DEBUG
#include <sys/syslog.h>
#endif
@@ -65,6 +69,7 @@
#ifndef SMP
#include <machine/clock.h>
#endif
+#include <machine/resource.h>
#include <machine/specialreg.h>
#include <machine/segments.h>
@@ -77,7 +82,6 @@
#include <i386/isa/isa.h>
#endif
#endif
-#include <i386/isa/isa_device.h>
/*
* 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
@@ -88,9 +92,6 @@
#define NPX_DISABLE_I586_OPTIMIZED_BZERO (1 << 1)
#define NPX_DISABLE_I586_OPTIMIZED_COPYIO (1 << 2)
-/* XXX - should be in header file. */
-ointhand2_t npxintr;
-
#ifdef __GNUC__
#define fldcw(addr) __asm("fldcw %0" : : "m" (*(addr)))
@@ -124,18 +125,17 @@ void stop_emulating __P((void));
typedef u_char bool_t;
-static int npxattach __P((struct isa_device *dvp));
-static int npxprobe __P((struct isa_device *dvp));
-static int npxprobe1 __P((struct isa_device *dvp));
+#define NPXIRQ 8
+
+static int npx_attach __P((device_t dev));
+ void npx_intr __P((void *));
+static int npx_probe __P((device_t dev));
+static int npx_probe1 __P((device_t dev));
#ifdef I586_CPU
static long timezero __P((const char *funcname,
void (*func)(void *buf, size_t len)));
#endif /* I586_CPU */
-struct isa_driver npxdriver = {
- npxprobe, npxattach, "npx",
-};
-
int hw_float; /* XXX currently just alias for npx_exists */
SYSCTL_INT(_hw,HW_FLOATINGPT, floatingpoint,
@@ -206,12 +206,13 @@ __asm(" \n\
* need to use interrupts. Return 1 if device exists.
*/
static int
-npxprobe(dvp)
- struct isa_device *dvp;
+npx_probe(dev)
+ device_t dev;
{
-#ifdef SMP
+/*#ifdef SMP*/
+#if 1
- return npxprobe1(dvp);
+ return npx_probe1(dev);
#else /* SMP */
@@ -228,7 +229,11 @@ npxprobe(dvp)
* install suitable handlers and run with interrupts enabled so we
* won't need to do so much here.
*/
- npx_intrno = NRSVIDT + ffs(dvp->id_irq) - 1;
+#ifdef PC98
+ npx_intrno = NRSVIDT + NPXIRQ;
+#else
+ npx_intrno = NRSVIDT + 13;
+#endif
save_eflags = read_eflags();
disable_intr();
#ifdef PC98
@@ -241,17 +246,17 @@ npxprobe(dvp)
save_idt_npxintr = idt[npx_intrno];
save_idt_npxtrap = idt[16];
#ifdef PC98
- outb(IO_ICU1 + 2, ~(IRQ_SLAVE | dvp->id_irq));
- outb(IO_ICU2 + 2, ~(dvp->id_irq >> 8));
+ outb(IO_ICU1 + 2, ~IRQ_SLAVE);
+ outb(IO_ICU2 + 2, ~(1 << (NPXIRQ - 8)));
#else
- outb(IO_ICU1 + 1, ~(IRQ_SLAVE | dvp->id_irq));
- outb(IO_ICU2 + 1, ~(dvp->id_irq >> 8));
+ outb(IO_ICU1 + 1, ~IRQ_SLAVE);
+ outb(IO_ICU2 + 1, ~(1 << (13 - 8)));
#endif
setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
npx_idt_probeintr = idt[npx_intrno];
enable_intr();
- result = npxprobe1(dvp);
+ result = npx_probe1(dev);
disable_intr();
#ifdef PC98
outb(IO_ICU1 + 2, save_icu1_mask);
@@ -269,8 +274,8 @@ npxprobe(dvp)
}
static int
-npxprobe1(dvp)
- struct isa_device *dvp;
+npx_probe1(dev)
+ device_t dev;
{
#ifndef SMP
u_short control;
@@ -314,21 +319,18 @@ npxprobe1(dvp)
*/
fninit();
-#ifdef SMP
-
+/*#ifdef SMP*/
+#if 1
/*
* Exception 16 MUST work for SMP.
*/
npx_irq13 = 0;
npx_ex16 = hw_float = npx_exists = 1;
- dvp->id_irq = 0; /* zap the interrupt */
- /*
- * special return value to flag that we do not
- * actually use any I/O registers
- */
- return (-1);
+ device_set_desc(dev, "math processor");
+ return (0);
-#else /* SMP */
+#else /* !SMP */
+ device_set_desc(dev, "math processor");
/*
* Don't use fwait here because it might hang.
@@ -378,14 +380,12 @@ npxprobe1(dvp)
* Good, exception 16 works.
*/
npx_ex16 = 1;
- dvp->id_irq = 0; /* zap the interrupt */
- /*
- * special return value to flag that we do not
- * actually use any I/O registers
- */
- return (-1);
+ return (0);
}
if (npx_intrs_while_probing != 0) {
+ int rid;
+ struct resource *r;
+ void *intr;
/*
* Bad, we are stuck with IRQ13.
*/
@@ -393,8 +393,40 @@ npxprobe1(dvp)
/*
* npxattach would be too late to set npx0_imask.
*/
- npx0_imask |= dvp->id_irq;
- return (IO_NPXSIZE);
+#ifdef PC98
+ npx0_imask |= (1 << NPXIRQ);
+#else
+ npx0_imask |= (1 << 13);
+#endif
+
+ /*
+ * We allocate these resources permanently,
+ * so there is no need to keep track of them.
+ */
+ rid = 0;
+ r = bus_alloc_resource(dev, SYS_RES_IOPORT,
+ &rid, IO_NPX, IO_NPX,
+ IO_NPXSIZE, RF_ACTIVE);
+ if (r == 0)
+ panic("npx: can't get ports");
+ rid = 0;
+#ifdef PC98
+ r = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &rid, NPXIRQ, NPXIRQ,
+ 1, RF_ACTIVE);
+#else
+ r = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &rid, 13, 13,
+ 1, RF_ACTIVE);
+#endif
+ if (r == 0)
+ panic("npx: can't get IRQ");
+ BUS_SETUP_INTR(device_get_parent(dev),
+ dev, r, npx_intr, 0, &intr);
+ if (intr == 0)
+ panic("npx: can't create intr");
+
+ return (0);
}
/*
* Worse, even IRQ13 is broken. Use emulator.
@@ -406,13 +438,7 @@ npxprobe1(dvp)
* emulator and say that it has been installed. XXX handle devices
* that aren't really devices better.
*/
- dvp->id_irq = 0;
- /*
- * special return value to flag that we do not
- * actually use any I/O registers
- */
- return (-1);
-
+ return (0);
#endif /* SMP */
}
@@ -420,14 +446,15 @@ npxprobe1(dvp)
* Attach routine - announce which it is, and wire into system
*/
int
-npxattach(dvp)
- struct isa_device *dvp;
+npx_attach(dev)
+ device_t dev;
{
- dvp->id_ointr = npxintr;
+ int flags;
- /* The caller has printed "irq 13" for the npx_irq13 case. */
- if (!npx_irq13) {
- printf("npx%d: ", dvp->id_unit);
+ device_print_prettyname(dev);
+ if (npx_irq13) {
+ printf("using IRQ 13 interface\n");
+ } else {
if (npx_ex16)
printf("INT 16 interface\n");
#if defined(MATH_EMULATE) || defined(GPL_MATH_EMULATE)
@@ -444,23 +471,26 @@ npxattach(dvp)
npxinit(__INITIAL_NPXCW__);
#ifdef I586_CPU
+ if (resource_int_value("npx", 0, "flags", &flags) != 0)
+ flags = 0;
+
if (cpu_class == CPUCLASS_586 && npx_ex16 &&
timezero("i586_bzero()", i586_bzero) <
timezero("bzero()", bzero) * 4 / 5) {
- if (!(dvp->id_flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) {
+ if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BCOPY)) {
bcopy_vector = i586_bcopy;
ovbcopy_vector = i586_bcopy;
}
- if (!(dvp->id_flags & NPX_DISABLE_I586_OPTIMIZED_BZERO))
+ if (!(flags & NPX_DISABLE_I586_OPTIMIZED_BZERO))
bzero = i586_bzero;
- if (!(dvp->id_flags & NPX_DISABLE_I586_OPTIMIZED_COPYIO)) {
+ if (!(flags & NPX_DISABLE_I586_OPTIMIZED_COPYIO)) {
copyin_vector = i586_copyin;
copyout_vector = i586_copyout;
}
}
#endif
- return (1); /* XXX unused */
+ return (0); /* XXX unused */
}
/*
@@ -537,8 +567,8 @@ npxexit(p)
* solution for signals other than SIGFPE.
*/
void
-npxintr(unit)
- int unit;
+npx_intr(dummy)
+ void *dummy;
{
int code;
struct intrframe *frame;
@@ -565,7 +595,7 @@ npxintr(unit)
/*
* Pass exception to process.
*/
- frame = (struct intrframe *)&unit; /* XXX */
+ frame = (struct intrframe *)&dummy; /* XXX */
if ((ISPL(frame->if_cs) == SEL_UPL) || (frame->if_eflags & PSL_VM)) {
/*
* Interrupt is essentially a trap, so we can afford to call
@@ -753,4 +783,31 @@ timezero(funcname, func)
}
#endif /* I586_CPU */
+static device_method_t npx_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, npx_probe),
+ DEVMETHOD(device_attach, npx_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 npx_driver = {
+ "npx",
+ npx_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+
+static devclass_t npx_devclass;
+
+/*
+ * We prefer to attach to the root nexus so that the usual case (exception 16)
+ * doesn't describe the processor as being `on isa'.
+ */
+DRIVER_MODULE(npx, nexus, npx_driver, npx_devclass, 0, 0);
+
#endif /* NNPX > 0 */
diff --git a/sys/pc98/pc98/pc98gdc.c b/sys/pc98/pc98/pc98gdc.c
index 6b4ac09..7f4570a 100644
--- a/sys/pc98/pc98/pc98gdc.c
+++ b/sys/pc98/pc98/pc98gdc.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pc98gdc.c,v 1.5 1999/02/06 09:30:19 kato Exp $
+ * $Id: pc98gdc.c,v 1.6 1999/03/02 12:34:24 kato Exp $
*/
#include "gdc.h"
@@ -52,8 +52,7 @@
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
-
-#include <i386/isa/isa_device.h>
+#include <isa/isavar.h>
#define TEXT_GDC IO_GDC1 /* 0x60 */
#define ROW 25
@@ -66,27 +65,36 @@
#define GDC_UNIT(dev) minor(dev)
#define GDC_MKMINOR(unit) (unit)
-static int gdcprobe(struct isa_device *dev);
-static int gdc_attach(struct isa_device *dev);
+typedef struct gdc_softc {
+ video_adapter_t *adp;
+} gdc_softc_t;
+
+#define GDC_SOFTC(unit) \
+ ((gdc_softc_t *)devclass_get_softc(gdc_devclass, unit))
+
+devclass_t gdc_devclass;
+
+static int gdcprobe(device_t dev);
+static int gdc_attach(device_t dev);
-struct isa_driver gdcdriver = {
- gdcprobe,
- gdc_attach,
+static device_method_t gdc_methods[] = {
+ DEVMETHOD(device_probe, gdcprobe),
+ DEVMETHOD(device_attach, gdc_attach),
+ { 0, 0 }
+};
+
+static driver_t gdcdriver = {
DRIVER_NAME,
- 0,
+ gdc_methods,
+ DRIVER_TYPE_TTY,
+ sizeof(gdc_softc_t),
};
-typedef struct gdc_softc {
- video_adapter_t *adp;
-} gdc_softc_t;
+DRIVER_MODULE(gdc, isa, gdcdriver, gdc_devclass, 0, 0);
static int gdc_probe_unit(int unit, gdc_softc_t *sc, int flags);
static int gdc_attach_unit(int unit, gdc_softc_t *sc, int flags);
-#define GDC_SOFTC(unit) (gdc_softc[unit])
-
-static gdc_softc_t *gdc_softc[NGDC];
-
#if FB_INSTALL_CDEV
static d_open_t gdcopen;
@@ -104,44 +112,22 @@ static struct cdevsw vga_cdevsw = {
#endif /* FB_INSTALL_CDEV */
static int
-gdcprobe(struct isa_device *dev)
+gdcprobe(device_t dev)
{
gdc_softc_t *sc;
- int error;
-
- if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
- return 0;
- sc = gdc_softc[dev->id_unit]
- = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
- if (sc == NULL)
- return 0;
-
- error = gdc_probe_unit(dev->id_unit, sc, dev->id_flags);
- if (error) {
- gdc_softc[dev->id_unit] = NULL;
- free(sc, M_DEVBUF);
- return 0;
- }
-
- dev->id_iobase = sc->adp->va_io_base;
- dev->id_maddr = (caddr_t)BIOS_PADDRTOVADDR(sc->adp->va_mem_base);
- dev->id_msize = sc->adp->va_mem_size;
- return sc->adp->va_io_size;
+ device_set_desc(dev, "Generic GDC");
+ sc = device_get_softc(dev);
+ return gdc_probe_unit(device_get_unit(dev), sc, isa_get_flags(dev));
}
static int
-gdc_attach(struct isa_device *dev)
+gdc_attach(device_t dev)
{
gdc_softc_t *sc;
- if (dev->id_unit >= sizeof(gdc_softc)/sizeof(gdc_softc[0]))
- return 0;
- sc = gdc_softc[dev->id_unit];
- if (sc == NULL)
- return 0;
-
- return ((gdc_attach_unit(dev->id_unit, sc, dev->id_flags)) ? 0 : 1);
+ sc = device_get_softc(dev);
+ return gdc_attach_unit(device_get_unit(dev), sc, isa_get_flags(dev));
}
static int
diff --git a/sys/pc98/pc98/pc98kbd.c b/sys/pc98/pc98/pc98kbd.c
index 731f463..a9d44f7 100644
--- a/sys/pc98/pc98/pc98kbd.c
+++ b/sys/pc98/pc98/pc98kbd.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: pc98kbd.c,v 1.4 1999/01/19 14:08:04 kato Exp $
+ * $Id: pc98kbd.c,v 1.5 1999/03/10 14:51:53 kato Exp $
*/
#include "pckbd.h"
@@ -39,10 +39,13 @@
#include <sys/kernel.h>
#include <sys/conf.h>
#include <sys/proc.h>
+#include <sys/module.h>
#include <sys/tty.h>
#include <sys/fcntl.h>
-#include <sys/bus.h>
#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
#include <machine/resource.h>
@@ -51,6 +54,9 @@
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
+#include <isa/isavar.h>
+#include <machine/lock.h>
+
#ifdef __i386__
#include <i386/isa/isa_device.h>
#endif
@@ -76,23 +82,30 @@ typedef struct pckbd_softc {
} pckbd_softc_t;
#define PC98KBD_SOFTC(unit) \
- (((unit) >= NPCKBD) ? NULL : pckbd_softc[(unit)])
+ ((pckbd_softc_t)devclass_get_softc(pckbd_devclass, unit))
-static pckbd_softc_t *pckbd_softc[NPCKBD];
+static devclass_t pckbd_devclass;
-static int pckbdprobe(struct isa_device *dev);
-static int pckbdattach(struct isa_device *dev);
+static int pckbdprobe(device_t dev);
+static int pckbdattach(device_t dev);
+static void pckbd_isa_intr(void *arg);
-static ointhand2_t pckbd_isa_intr;
+static device_method_t pckbd_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pckbdprobe),
+ DEVMETHOD(device_attach, pckbdattach),
+ { 0, 0 }
+};
-/* driver declaration for isa_devtab_tty[] */
-struct isa_driver pckbddriver = {
- pckbdprobe,
- pckbdattach,
+static driver_t pckbd_driver = {
DRIVER_NAME,
- 0,
+ pckbd_methods,
+ DRIVER_TYPE_TTY,
+ sizeof(pckbd_softc_t),
};
+DRIVER_MODULE(pckbd, isa, pckbd_driver, pckbd_devclass, 0, 0);
+
static int pckbd_probe_unit(int unit, int port, int irq,
int flags);
static int pckbd_attach_unit(int unit, pckbd_softc_t *sc,
@@ -117,36 +130,41 @@ static struct cdevsw pckbd_cdevsw = {
#endif /* KBD_INSTALL_CDEV */
static int
-pckbdprobe(struct isa_device *dev)
+pckbdprobe(device_t dev)
{
- return ((pckbd_probe_unit(dev->id_unit, dev->id_iobase, dev->id_irq,
- dev->id_flags)) ? 0 : IO_KBDSIZE);
+ device_set_desc(dev, "PC-98 Keyboard");
+
+ return pckbd_probe_unit(device_get_unit(dev), isa_get_port(dev),
+ (1 << isa_get_irq(dev)), isa_get_flags(dev));
}
static int
-pckbdattach(struct isa_device *dev)
+pckbdattach(device_t dev)
{
- pckbd_softc_t *sc;
+ void *ih;
+ struct resource *res;
+ int zero = 0;
- if (dev->id_unit >= sizeof(pckbd_softc)/sizeof(pckbd_softc[0]))
- return 0;
- sc = pckbd_softc[dev->id_unit]
- = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
- if (sc == NULL)
- return 0;
+ pckbd_softc_t *sc = device_get_softc(dev);
bzero(sc, sizeof(*sc));
- dev->id_ointr = pckbd_isa_intr;
- return ((pckbd_attach_unit(dev->id_unit, sc, dev->id_iobase,
- dev->id_irq, dev->id_flags)) ? 0 : 1);
+ pckbd_attach_unit(device_get_unit(dev), sc, isa_get_port(dev),
+ (1 << isa_get_irq(dev)), isa_get_flags(dev));
+
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, 0ul, ~0ul, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ BUS_SETUP_INTR(device_get_parent(dev), dev, res, pckbd_isa_intr,
+ sc, &ih);
+
+ return (0);
}
static void
-pckbd_isa_intr(int unit)
+pckbd_isa_intr(void *arg)
{
- keyboard_t *kbd;
+ pckbd_softc_t *sc = arg;
+ keyboard_t *kbd = sc->kbd;
- kbd = pckbd_softc[unit]->kbd;
(*kbdsw[kbd->kb_index]->intr)(kbd, NULL);
}
@@ -414,15 +432,14 @@ pckbd_configure(int flags)
{
keyboard_t *kbd;
int arg[2];
- struct isa_device *dev;
int i;
/* XXX: a kludge to obtain the device configuration flags */
- dev = find_isadev(isa_devtab_tty, &pckbddriver, 0);
- if (dev != NULL) {
- flags |= dev->id_flags;
+ if (resource_int_value(DRIVER_NAME, 0, "flags", &i) == 0) {
+ flags |= i;
/* if the driver is disabled, unregister the keyboard if any */
- if (!dev->id_enabled) {
+ if (resource_int_value(DRIVER_NAME, 0, "disabled", &i) == 0
+ && i != 0) {
i = kbd_find_keyboard(DRIVER_NAME, PC98KBD_DEFAULT);
if (i >= 0) {
kbd = kbd_get_keyboard(i);
diff --git a/sys/pc98/pc98/sio.c b/sys/pc98/pc98/sio.c
index 962d4f9..94adb71 100644
--- a/sys/pc98/pc98/sio.c
+++ b/sys/pc98/pc98/sio.c
@@ -31,16 +31,17 @@
* SUCH DAMAGE.
*
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
- * $Id: sio.c,v 1.84 1999/04/01 13:44:15 kato Exp $
+ * $Id: sio.c,v 1.85 1999/04/03 15:51:14 kato Exp $
*/
#include "opt_comconsole.h"
#include "opt_compat.h"
#include "opt_ddb.h"
#include "opt_devfs.h"
-#include "opt_sio.h"
+/* #include "opt_sio.h" */
#include "sio.h"
-#include "pnp.h"
+/* #include "pnp.h" */
+#define NPNP 0
/*
* Serial driver, based on 386BSD-0.1 com driver.
@@ -141,6 +142,7 @@
#include <sys/malloc.h>
#include <sys/tty.h>
#include <sys/proc.h>
+#include <sys/module.h>
#include <sys/conf.h>
#include <sys/dkstat.h>
#include <sys/fcntl.h>
@@ -148,28 +150,32 @@
#include <sys/kernel.h>
#include <sys/syslog.h>
#include <sys/sysctl.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
#ifdef DEVFS
#include <sys/devfsext.h>
#endif
#include <sys/timepps.h>
-#include <machine/clock.h>
-#include <machine/ipl.h>
-#ifndef SMP
-#include <machine/lock.h>
-#endif
-
#ifdef PC98
#include <pc98/pc98/pc98.h>
#include <pc98/pc98/pc98_machdep.h>
-#include <i386/isa/icu.h>
#include <i386/isa/ic/i8251.h>
#else
-#include <i386/isa/isa.h>
+#include <isa/isareg.h>
+#endif
+#include <isa/isavar.h>
+#include <machine/lock.h>
+
+#include <machine/clock.h>
+#include <machine/ipl.h>
+#ifndef SMP
+#include <machine/lock.h>
#endif
-#include <i386/isa/isa_device.h>
-#include <i386/isa/sioreg.h>
-#include <i386/isa/intr_machdep.h>
+#include <machine/resource.h>
+
+#include <isa/sioreg.h>
#ifdef COM_ESP
#include <i386/isa/ic/esp.h>
@@ -179,6 +185,8 @@
#include <i386/isa/ic/rsa.h>
#endif
+#if 0
+
#include "card.h"
#if NCARD > 0
#include <sys/module.h>
@@ -190,6 +198,13 @@
#include <i386/isa/pnp.h>
#endif
+#endif
+
+#ifndef __i386__
+#define disable_intr() 0
+#define enable_intr() 0
+#endif
+
#ifdef SMP
#define disable_intr() COM_DISABLE_INTR()
#define enable_intr() COM_ENABLE_INTR()
@@ -219,22 +234,22 @@
/* checks in flags for multiport and which is multiport "master chip"
* for a given card
*/
-#define COM_ISMULTIPORT(dev) ((dev)->id_flags & 0x01)
-#define COM_MPMASTER(dev) (((dev)->id_flags >> 8) & 0x0ff)
-#define COM_NOTAST4(dev) ((dev)->id_flags & 0x04)
+#define COM_ISMULTIPORT(flags) ((flags) & 0x01)
+#define COM_MPMASTER(flags) (((flags) >> 8) & 0x0ff)
+#define COM_NOTAST4(flags) ((flags) & 0x04)
#endif /* COM_MULTIPORT */
-#define COM_CONSOLE(dev) ((dev)->id_flags & 0x10)
-#define COM_FORCECONSOLE(dev) ((dev)->id_flags & 0x20)
-#define COM_LLCONSOLE(dev) ((dev)->id_flags & 0x40)
-#define COM_LOSESOUTINTS(dev) ((dev)->id_flags & 0x08)
-#define COM_NOFIFO(dev) ((dev)->id_flags & 0x02)
-#define COM_ST16650A(dev) ((dev)->id_flags & 0x20000)
-#define COM_C_NOPROBE (0x40000)
-#define COM_NOPROBE(dev) ((dev)->id_flags & COM_C_NOPROBE)
-#define COM_C_IIR_TXRDYBUG (0x80000)
-#define COM_IIR_TXRDYBUG(dev) ((dev)->id_flags & COM_C_IIR_TXRDYBUG)
-#define COM_FIFOSIZE(dev) (((dev)->id_flags & 0xff000000) >> 24)
+#define COM_CONSOLE(flags) ((flags) & 0x10)
+#define COM_FORCECONSOLE(flags) ((flags) & 0x20)
+#define COM_LLCONSOLE(flags) ((flags) & 0x40)
+#define COM_LOSESOUTINTS(flags) ((flags) & 0x08)
+#define COM_NOFIFO(flags) ((flags) & 0x02)
+#define COM_ST16650A(flags) ((flags) & 0x20000)
+#define COM_C_NOPROBE (0x40000)
+#define COM_NOPROBE(flags) ((flags) & COM_C_NOPROBE)
+#define COM_C_IIR_TXRDYBUG (0x80000)
+#define COM_IIR_TXRDYBUG(flags) ((flags) & COM_C_IIR_TXRDYBUG)
+#define COM_FIFOSIZE(flags) (((flags) & 0xff000000) >> 24)
#ifdef PC98
#define com_emr com_msr /* Extension mode register for RSB-2000/3000 */
@@ -294,7 +309,7 @@ struct lbq {
/* com device structure */
struct com_s {
- u_int id_flags; /* Copy isa device falgas */
+ u_int flags; /* Copy isa device flags */
u_char state; /* miscellaneous flag bits */
bool_t active_out; /* nonzero if the callout device is open */
u_char cfcr_image; /* copy of value written to CFCR */
@@ -415,17 +430,18 @@ struct com_s {
static int espattach __P((struct isa_device *isdp, struct com_s *com,
Port_t esp_port));
#endif
-static int sioattach __P((struct isa_device *dev));
+static int sioattach __P((device_t dev));
+
static timeout_t siobusycheck;
static timeout_t siodtrwakeup;
static void comhardclose __P((struct com_s *com));
static void sioinput __P((struct com_s *com));
-static ointhand2_t siointr;
static void siointr1 __P((struct com_s *com));
+static void siointr __P((void *arg));
static int commctl __P((struct com_s *com, int bits, int how));
static int comparam __P((struct tty *tp, struct termios *t));
static swihand_t siopoll;
-static int sioprobe __P((struct isa_device *dev));
+static int sioprobe __P((device_t dev));
static void siosettimeout __P((void));
static int siosetwater __P((struct com_s *com, speed_t speed));
static void comstart __P((struct tty *tp));
@@ -437,11 +453,23 @@ static void disc_optim __P((struct tty *tp, struct termios *t,
static char driver_name[] = "sio";
/* table and macro for fast conversion from a unit number to its com struct */
-static struct com_s *p_com_addr[NSIOTOT];
-#define com_addr(unit) (p_com_addr[unit])
+static devclass_t sio_devclass;
+#define com_addr(unit) ((struct com_s *) \
+ devclass_get_softc(sio_devclass, unit))
+
+static device_method_t sio_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, sioprobe),
+ DEVMETHOD(device_attach, sioattach),
+
+ { 0, 0 }
+};
-struct isa_driver siodriver = {
- sioprobe, sioattach, driver_name
+static driver_t sio_driver = {
+ driver_name,
+ sio_methods,
+ DRIVER_TYPE_TTY,
+ sizeof(struct com_s),
};
static d_open_t sioopen;
@@ -461,10 +489,12 @@ static struct cdevsw sio_cdevsw = {
D_TTY,
};
-static int comconsole = -1;
+int comconsole = -1;
static volatile speed_t comdefaultrate = CONSPEED;
+static volatile speed_t gdbdefaultrate = CONSPEED;
static u_int com_events; /* input chars + weighted output completions */
static Port_t siocniobase;
+static Port_t siogdbiobase;
static bool_t sio_registered;
static int sio_timeout;
static int sio_timeouts_until_log;
@@ -518,7 +548,7 @@ static void pc98_i8251_set_cmd __P((struct com_s *com, int x));
static void pc98_i8251_or_cmd __P((struct com_s *com, int x));
static void pc98_i8251_clear_cmd __P((struct com_s *com, int x));
static void pc98_i8251_clear_or_cmd __P((struct com_s *com, int clr, int x));
-static int pc98_check_if_type __P((struct isa_device *dev, struct siodev *iod));
+static int pc98_check_if_type __P((device_t dev, struct siodev *iod));
static void pc98_check_sysclock __P((void));
static int pc98_set_ioport __P((struct com_s *com, int id_flags));
@@ -936,20 +966,24 @@ card_intr(struct pccard_devinfo *devi)
}
#endif /* NCARD > 0 */
+#define SET_FLAG(dev, bit) isa_set_flags(dev, isa_get_flags(dev) | (bit))
+#define CLR_FLAG(dev, bit) isa_set_flags(dev, isa_get_flags(dev) & ~(bit))
+
static int
sioprobe(dev)
- struct isa_device *dev;
+ device_t dev;
{
static bool_t already_init;
bool_t failures[10];
int fn;
- struct isa_device *idev;
+ device_t idev;
Port_t iobase;
intrmask_t irqmap[4];
intrmask_t irqs;
u_char mcr_image;
int result;
- struct isa_device *xdev;
+ device_t xdev;
+ u_int flags = isa_get_flags(dev);
#ifdef PC98
int irqout=0;
int ret = 0;
@@ -966,33 +1000,37 @@ sioprobe(dev)
* from any used port that shares the interrupt vector.
* XXX the gate enable is elsewhere for some multiports.
*/
- for (xdev = isa_devtab_tty; xdev->id_driver != NULL; xdev++)
+ device_t *devs;
+ int count, i;
+
+ devclass_get_devices(sio_devclass, &devs, &count);
#ifdef PC98
- if (xdev->id_driver == &siodriver && xdev->id_enabled) {
- tmp = (xdev->id_flags >> 24) & 0xff;
+ for (i = 0; i < count; i++) {
+ xdev = devs[i];
+ tmp = (flags >> 24) & 0xff;
if (IS_8251(tmp))
- outb((xdev->id_iobase & 0xff00) | PC98SIO_cmd_port(tmp & 0x0f), 0xf2);
+ outb((isa_get_port(xdev) & 0xff00) | PC98SIO_cmd_port(tmp & 0x0f), 0xf2);
else
if (tmp == COM_IF_RSA98III) {
- rsabase = xdev->id_iobase & 0xfff0;
-#if 0
- if (rsabase != xdev->id_iobase)
- return(0);
-#endif
- outb(xdev->id_iobase + 8 + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
+ rsabase = isa_get_port(xdev) & 0xfff0;
+ outb(isa_get_port(xdev) + 8 + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
} else
- outb(xdev->id_iobase + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
- }
+ outb(isa_get_port(xdev) + (com_mcr << if_16550a_type[tmp & 0x0f].port_shift), 0);
+ }
#else
- if (xdev->id_driver == &siodriver && xdev->id_enabled)
- outb(xdev->id_iobase + com_mcr, 0);
+ for (i = 0; i < count; i++) {
+ xdev = devs[i];
+ outb(isa_get_port(xdev) + com_mcr, 0);
+ }
#endif
+ free(devs, M_TEMP);
already_init = TRUE;
}
- if (COM_LLCONSOLE(dev)) {
- printf("sio%d: reserved for low-level i/o\n", dev->id_unit);
- return (0);
+ if (COM_LLCONSOLE(flags)) {
+ printf("sio%d: reserved for low-level i/o\n",
+ device_get_unit(dev));
+ return (ENXIO);
}
#ifdef PC98
@@ -1002,9 +1040,9 @@ sioprobe(dev)
* If the port is i8251 UART (internal, B98_01)
*/
if (pc98_check_if_type(dev, &iod) == -1)
- return 0;
+ return 0;
if (iod.irq > 0)
- dev->id_irq = 1 << iod.irq;
+ isa_set_irq(dev, iod.irq);
if (IS_8251(iod.if_type)) {
outb(iod.cmd, 0);
DELAY(10);
@@ -1055,8 +1093,8 @@ sioprobe(dev)
#ifdef PC98
if (iod.if_type == COM_IF_RSA98III) {
mcr_image = 0;
- rsabase = idev->id_iobase & 0xfff0;
- if (rsabase != idev->id_iobase)
+ rsabase = isa_get_port(idev) & 0xfff0;
+ if (rsabase != isa_get_port(idev))
return(0);
outb(rsabase + rsa_msr, 0x04);
outb(rsabase + rsa_frr, 0x00);
@@ -1069,51 +1107,50 @@ sioprobe(dev)
}
#endif /* PC98 */
#ifdef COM_MULTIPORT
- if (COM_ISMULTIPORT(dev)) {
- idev = find_isadev(isa_devtab_tty, &siodriver,
- COM_MPMASTER(dev));
+ if (COM_ISMULTIPORT(flags)) {
+ idev = devclass_get_device(sio_devclass, COM_MPMASTER(flags));
if (idev == NULL) {
printf("sio%d: master device %d not configured\n",
- dev->id_unit, COM_MPMASTER(dev));
- dev->id_irq = 0;
+ device_get_unit(dev), COM_MPMASTER(flags));
+ isa_set_irq(dev, 0);
idev = dev;
}
#ifndef PC98
- if (!COM_NOTAST4(dev)) {
- outb(idev->id_iobase + com_scr,
- idev->id_irq ? 0x80 : 0);
+ if (!COM_NOTAST4(flags)) {
+ outb(isa_get_port(idev) + com_scr,
+ isa_get_irq(idev) >= 0 ? 0x80 : 0);
mcr_image = 0;
}
#endif /* !PC98 */
}
#endif /* COM_MULTIPORT */
- if (idev->id_irq == 0)
+ if (isa_get_irq(idev) < 0)
mcr_image = 0;
#ifdef PC98
tmp = if_16550a_type[iod.if_type & 0x0f].irr_write;
if (tmp != -1) {
/* MC16550II */
- switch (idev->id_irq) {
- case IRQ3: irqout = 4; break;
- case IRQ5: irqout = 5; break;
- case IRQ6: irqout = 6; break;
- case IRQ12: irqout = 7; break;
+ 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", dev->id_unit);
+ printf("sio%d: irq configuration error\n",
+ device_get_unit(dev));
return (0);
}
- outb((dev->id_iobase & 0x00ff) | tmp, irqout);
+ outb((isa_get_port(dev) & 0x00ff) | tmp, irqout);
}
port_shift = if_16550a_type[iod.if_type & 0x0f].port_shift;
#endif
bzero(failures, sizeof failures);
+ iobase = isa_get_port(dev);
#ifdef PC98
if (iod.if_type == COM_IF_RSA98III)
- iobase = dev->id_iobase + 8;
- else
+ iobase += 8;
#endif
- iobase = dev->id_iobase;
/*
* We don't want to get actual interrupts, just masked ones.
@@ -1190,9 +1227,8 @@ sioprobe(dev)
*/
#ifdef PC98
outb(iobase + (com_ier << port_shift), IER_ETXRDY);
- if (iod.if_type == COM_IF_RSA98III) {
+ if (iod.if_type == COM_IF_RSA98III)
outb(rsabase + rsa_ier, 0x04);
- }
#else
outb(iobase + com_ier, IER_ETXRDY);
#endif /* PC98 */
@@ -1228,7 +1264,7 @@ sioprobe(dev)
* It's a definitly Serial PCMCIA(16550A), but still be required
* for IIR_TXRDY implementation ( Palido 321s, DC-1S... )
*/
- if ( COM_NOPROBE(dev) ) {
+ if ( COM_NOPROBE(flags) ) {
/* Reading IIR register twice */
for ( fn = 0; fn < 2; fn ++ ) {
DELAY(10000);
@@ -1240,10 +1276,12 @@ sioprobe(dev)
}
/* Check IIR_TXRDY clear ? */
#ifdef PC98
- result = if_16550a_type[iod.if_type & 0x0f].io_size;
+ isa_set_portsize(dev,
+ if_16550a_type[iod.if_type & 0x0f].io_size);
#else
- result = IO_COMSIZE;
+ isa_set_portsize(dev, IO_COMSIZE);
#endif
+ result = 0;
if ( failures[6] & IIR_TXRDY ) {
/* Nop, Double check with clearing IER */
#ifdef PC98
@@ -1255,14 +1293,14 @@ sioprobe(dev)
if ( inb(iobase + com_iir) & IIR_NOPEND ) {
#endif
/* Ok. we're familia this gang */
- dev->id_flags |= COM_C_IIR_TXRDYBUG; /* Set IIR_TXRDYBUG */
+ SET_FLAG(dev, COM_C_IIR_TXRDYBUG); /* Set IIR_TXRDYBUG */
} else {
/* Unknow, Just omit this chip.. XXX*/
- result = 0;
+ result = ENXIO;
}
} else {
/* OK. this is well-known guys */
- dev->id_flags &= ~COM_C_IIR_TXRDYBUG; /*Clear IIR_TXRDYBUG*/
+ CLR_FLAG(dev, COM_C_IIR_TXRDYBUG); /*Clear IIR_TXRDYBUG*/
}
#ifdef PC98
outb(iobase + (com_cfcr << port_shift), CFCR_8BITS);
@@ -1270,7 +1308,7 @@ sioprobe(dev)
outb(iobase + com_cfcr, CFCR_8BITS);
#endif
enable_intr();
- return (iobase == siocniobase ? IO_COMSIZE : result);
+ return (iobase == siocniobase ? 0 : result);
}
/*
@@ -1296,9 +1334,8 @@ sioprobe(dev)
#ifdef PC98
failures[4] = (inb(iobase + (com_iir << port_shift)) & IIR_IMASK)
- IIR_TXRDY;
- if (iod.if_type == COM_IF_RSA98III) {
+ if (iod.if_type == COM_IF_RSA98III)
inb(rsabase + rsa_srr);
- }
#else
failures[4] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_TXRDY;
#endif
@@ -1307,9 +1344,8 @@ sioprobe(dev)
#ifdef PC98
failures[6] = (inb(iobase + (com_iir << port_shift)) & IIR_IMASK)
- IIR_NOPEND;
- if (iod.if_type == COM_IF_RSA98III) {
+ if (iod.if_type == COM_IF_RSA98III)
inb(rsabase + rsa_srr);
- }
#else
failures[6] = (inb(iobase + com_iir) & IIR_IMASK) - IIR_NOPEND;
#endif
@@ -1319,7 +1355,7 @@ sioprobe(dev)
* 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.
+ * (unless there is another device driving at) 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.)
*/
@@ -1327,9 +1363,8 @@ sioprobe(dev)
outb(iobase + (com_ier << port_shift), 0);
outb(iobase + (com_cfcr << port_shift), CFCR_8BITS);
failures[7] = inb(iobase + (com_ier << port_shift));
- if (iod.if_type == COM_IF_RSA98III) {
+ if (iod.if_type == COM_IF_RSA98III)
outb(rsabase + rsa_ier, 0x00);
- }
#else
outb(iobase + com_ier, 0);
outb(iobase + com_cfcr, CFCR_8BITS); /* dummy to avoid bus echo */
@@ -1351,19 +1386,21 @@ sioprobe(dev)
enable_intr();
irqs = irqmap[1] & ~irqmap[0];
- if (idev->id_irq != 0 && (idev->id_irq & irqs) == 0)
+ if (isa_get_irq(idev) >= 0 && ((1 << isa_get_irq(idev)) & irqs) == 0)
printf(
"sio%d: configured irq %d not in bitmap of probed irqs %#x\n",
- dev->id_unit, ffs(idev->id_irq) - 1, irqs);
+ device_get_unit(dev), isa_get_irq(idev), irqs);
if (bootverbose)
printf("sio%d: irq maps: %#x %#x %#x %#x\n",
- dev->id_unit, irqmap[0], irqmap[1], irqmap[2], irqmap[3]);
+ device_get_unit(dev),
+ irqmap[0], irqmap[1], irqmap[2], irqmap[3]);
#ifdef PC98
- result = if_16550a_type[iod.if_type & 0x0f].io_size;
+ isa_set_portsize(dev, if_16550a_type[iod.if_type & 0x0f].io_size);
#else
- result = IO_COMSIZE;
+ isa_set_portsize(dev, IO_COMSIZE);
#endif
+ result = 0;
for (fn = 0; fn < sizeof failures; ++fn)
if (failures[fn]) {
#ifdef PC98
@@ -1371,10 +1408,10 @@ sioprobe(dev)
#else
outb(iobase + com_mcr, 0);
#endif
- result = 0;
+ result = ENXIO;
if (bootverbose) {
printf("sio%d: probe failed test(s):",
- dev->id_unit);
+ device_get_unit(dev));
for (fn = 0; fn < sizeof failures; ++fn)
if (failures[fn])
printf(" %d", fn);
@@ -1382,7 +1419,7 @@ sioprobe(dev)
}
break;
}
- return (iobase == siocniobase ? IO_COMSIZE : result);
+ return (iobase == siocniobase ? 0 : result);
}
#ifdef COM_ESP
@@ -1467,44 +1504,44 @@ espattach(isdp, com, esp_port)
#endif /* COM_ESP */
static int
-sioattach(isdp)
- struct isa_device *isdp;
+sioattach(dev)
+ device_t dev;
{
struct com_s *com;
- dev_t dev;
#ifdef COM_ESP
Port_t *espp;
#endif
-#ifdef COM_MULTIPORT
- struct isa_device *idev;
-#endif
Port_t iobase;
int s;
int unit;
+ void *ih;
+ struct resource *res;
+ int zero = 0;
+ u_int flags = isa_get_flags(dev);
#ifdef PC98
int port_shift = 0;
+ u_char *obuf;
u_long obufsize;
#endif
- isdp->id_ointr = siointr;
+#if 0
isdp->id_ri_flags |= RI_FAST;
+#endif
+ iobase = isa_get_port(dev);
#ifdef PC98
- if (((isdp->id_flags >> 24) & 0xff) == COM_IF_RSA98III)
- iobase = isdp->id_iobase + 8;
- else
+ if (((flags >> 24) & 0xff) == COM_IF_RSA98III)
+ iobase += 8;
#endif
- iobase = isdp->id_iobase;
- unit = isdp->id_unit;
-#ifndef PC98
- com = malloc(sizeof *com, M_DEVBUF, M_NOWAIT);
-#else
+ unit = device_get_unit(dev);
+ com = device_get_softc(dev);
+#ifdef PC98
obufsize = 256;
- if (((isdp->id_flags >> 24) & 0xff) == COM_IF_RSA98III)
+ if (((flags >> 24) & 0xff) == COM_IF_RSA98III)
obufsize = 2048;
- com = malloc((sizeof *com) + obufsize * 2, M_DEVBUF, M_NOWAIT);
-#endif
- if (com == NULL)
+ if ((obuf = malloc(obufsize * 2, M_DEVBUF, M_NOWAIT)) == NULL)
return (0);
+ bzero(obuf, obufsize * 2);
+#endif
/*
* sioprobe() has initialized the device registers as follows:
@@ -1521,23 +1558,22 @@ sioattach(isdp)
bzero(com, sizeof *com);
#ifdef PC98
com->obufsize = obufsize;
- com->obuf1 = (u_char *)com + (sizeof *com);
- com->obuf2 = com->obuf1 + obufsize;
- bzero(com->obuf1, obufsize * 2);
+ com->obuf1 = obuf;
+ com->obuf2 = obuf + obufsize;
#endif
com->unit = unit;
com->cfcr_image = CFCR_8BITS;
com->dtr_wait = 3 * hz;
- com->loses_outints = COM_LOSESOUTINTS(isdp) != 0;
- com->no_irq = isdp->id_irq == 0;
+ com->loses_outints = COM_LOSESOUTINTS(flags) != 0;
+ com->no_irq = isa_get_irq(dev) < 0;
com->tx_fifo_size = 1;
com->obufs[0].l_head = com->obuf1;
com->obufs[1].l_head = com->obuf2;
com->iobase = iobase;
#ifdef PC98
- if (pc98_set_ioport(com, isdp->id_flags) == -1) {
- com->pc98_if_type = (isdp->id_flags >> 24) & 0xff;
+ if (pc98_set_ioport(com, isa_get_flags(dev)) == -1) {
+ com->pc98_if_type = (isa_get_flags(dev) >> 24) & 0xff;
port_shift = if_16550a_type[com->pc98_if_type & 0x0f].port_shift;
com->data_port = iobase + (com_data << port_shift);
com->int_id_port = iobase + (com_iir << port_shift);
@@ -1597,9 +1633,9 @@ sioattach(isdp)
#ifndef PC98
#ifdef COM_MULTIPORT
- if (!COM_ISMULTIPORT(isdp) && !COM_IIR_TXRDYBUG(isdp))
+ if (!COM_ISMULTIPORT(flags) && !COM_IIR_TXRDYBUG(flags))
#else
- if (!COM_IIR_TXRDYBUG(isdp))
+ if (!COM_IIR_TXRDYBUG(flags))
#endif
{
u_char scr;
@@ -1643,7 +1679,7 @@ sioattach(isdp)
printf(" 16550?");
break;
case FIFO_RX_HIGH:
- if (COM_NOFIFO(isdp)) {
+ if (COM_NOFIFO(flags)) {
printf(" 16550A fifo disabled");
} else {
com->hasfifo = TRUE;
@@ -1651,12 +1687,12 @@ sioattach(isdp)
com->tx_fifo_size = 0; /* XXX flag conflicts. */
printf(" 16550A");
#else
- if (COM_ST16650A(isdp)) {
+ if (COM_ST16650A(flags)) {
com->st16650a = 1;
com->tx_fifo_size = 32;
printf(" ST16650A");
} else {
- com->tx_fifo_size = COM_FIFOSIZE(isdp);
+ com->tx_fifo_size = COM_FIFOSIZE(flags);
printf(" 16550A");
}
#endif
@@ -1664,7 +1700,7 @@ sioattach(isdp)
#ifdef PC98
if (com->pc98_if_type == COM_IF_RSA98III) {
com->tx_fifo_size = 2048;
- com->rsabase = isdp->id_iobase;
+ com->rsabase = isa_get_port(dev);
outb(com->rsabase + rsa_ier, 0x00);
outb(com->rsabase + rsa_frr, 0x00);
}
@@ -1675,7 +1711,7 @@ sioattach(isdp)
if (com->pc98_if_type == COM_IF_ESP98)
#endif
for (espp = likely_esp_ports; *espp != 0; espp++)
- if (espattach(isdp, com, *espp)) {
+ if (espattach(dev, com, *espp)) {
com->tx_fifo_size = 1024;
break;
}
@@ -1761,15 +1797,15 @@ determined_type: ;
#endif
#ifdef COM_MULTIPORT
- if (COM_ISMULTIPORT(isdp)) {
+ if (COM_ISMULTIPORT(flags)) {
com->multiport = TRUE;
printf(" (multiport");
- if (unit == COM_MPMASTER(isdp))
+ if (unit == COM_MPMASTER(flags))
printf(" master");
printf(")");
- idev = find_isadev(isa_devtab_tty, &siodriver,
- COM_MPMASTER(isdp));
- com->no_irq = (idev == NULL || idev->id_irq == 0);
+ com->no_irq =
+ isa_get_irq(devclass_get_device
+ (sio_devclass, COM_MPMASTER(flags))) < 0;
}
#endif /* COM_MULTIPORT */
#ifdef PC98
@@ -1777,17 +1813,11 @@ determined_type: ;
#endif
if (unit == comconsole)
printf(", console");
- if ( COM_IIR_TXRDYBUG(isdp) )
+ if ( COM_IIR_TXRDYBUG(flags) )
printf(" with a bogus IIR_TXRDY register");
printf("\n");
- s = spltty();
- com_addr(unit) = com;
- splx(s);
-
if (!sio_registered) {
- dev = makedev(CDEV_MAJOR, 0);
- cdevsw_add(&dev, &sio_cdevsw, NULL);
register_swi(SWI_TTY, siopoll);
sio_registered = TRUE;
}
@@ -1811,10 +1841,16 @@ determined_type: ;
unit | CALLOUT_MASK | CONTROL_LOCK_STATE, DV_CHR,
UID_UUCP, GID_DIALER, 0660, "cuala%r", unit);
#endif
- com->id_flags = isdp->id_flags; /* Heritate id_flags for later */
+ com->flags = isa_get_flags(dev); /* Heritate id_flags for later */
com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR;
pps_init(&com->pps);
- return (1);
+
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, 0ul, ~0ul, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ BUS_SETUP_INTR(device_get_parent(dev), dev, res, siointr, com,
+ &ih);
+
+ return (0);
}
static int
@@ -1995,7 +2031,7 @@ open_top:
(void) inb(com->data_port);
com->prev_modem_status = com->last_modem_status
= inb(com->modem_status_port);
- if (COM_IIR_TXRDYBUG(com)) {
+ if (COM_IIR_TXRDYBUG(com->flags)) {
outb(com->intr_ctl_port, IER_ERXRDY | IER_ERLS
| IER_EMSC);
} else {
@@ -2093,10 +2129,9 @@ sioclose(dev, flag, mode, p)
if (com->gone) {
printf("sio%d: gone\n", com->unit);
s = spltty();
- com_addr(com->unit) = NULL;
if (com->ibuf != NULL)
free(com->ibuf, M_DEVBUF);
- bzero(tp, sizeof *tp);
+ bzero(tp,sizeof *tp);
free(com, M_DEVBUF);
splx(s);
}
@@ -2402,16 +2437,15 @@ sioinput(com)
#endif
}
-static void
-siointr(unit)
- int unit;
+void
+siointr(arg)
+ void *arg;
{
#ifndef COM_MULTIPORT
COM_LOCK();
- siointr1(com_addr(unit));
+ siointr1((struct com_s *) arg);
COM_UNLOCK();
#else /* COM_MULTIPORT */
- struct com_s *com;
bool_t possibly_more_intrs;
#ifdef PC98
u_char rsa_buf_status;
@@ -2714,7 +2748,7 @@ cont:
com_int_Tx_enable(com);
#endif
com->obufq.l_head = ioptr;
- if (COM_IIR_TXRDYBUG(com)) {
+ if (COM_IIR_TXRDYBUG(com->flags)) {
int_ctl_new = int_ctl | IER_ETXRDY;
}
if (ioptr >= com->obufq.l_tail) {
@@ -2729,7 +2763,7 @@ cont:
com->obufq.l_next = qp;
} else {
/* output just completed */
- if ( COM_IIR_TXRDYBUG(com) ) {
+ if ( COM_IIR_TXRDYBUG(com->flags) ) {
int_ctl_new = int_ctl & ~IER_ETXRDY;
}
com->state &= ~CS_BUSY;
@@ -2745,7 +2779,7 @@ cont:
setsofttty(); /* handle at high level ASAP */
}
}
- if ( COM_IIR_TXRDYBUG(com) && (int_ctl != int_ctl_new)) {
+ if ( COM_IIR_TXRDYBUG(com->flags) && (int_ctl != int_ctl_new)) {
#ifdef PC98
if (com->pc98_if_type == COM_IF_RSA98III) {
int_ctl_new &= ~(IER_ETXRDY | IER_ERXRDY);
@@ -2794,7 +2828,7 @@ sioioctl(dev, cmd, data, flag, p)
int s;
struct tty *tp;
#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
- int oldcmd;
+ u_long oldcmd;
struct termios term;
#endif
@@ -3872,10 +3906,11 @@ struct siocnstate {
};
static speed_t siocngetspeed __P((Port_t, struct speedtab *));
-static void siocnclose __P((struct siocnstate *sp));
-static void siocnopen __P((struct siocnstate *sp));
-static void siocntxwait __P((void));
+static void siocnclose __P((struct siocnstate *sp, Port_t iobase));
+static void siocnopen __P((struct siocnstate *sp, Port_t iobase, int speed));
+static void siocntxwait __P((Port_t iobase));
+#ifdef __i386__
/*
* XXX: sciocnget() and sciocnputc() are not declared static, as they are
* referred to from i386/i386/i386-gdbstub.c.
@@ -3888,8 +3923,11 @@ static cn_checkc_t siocncheckc;
CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
+#endif
+
static void
-siocntxwait()
+siocntxwait(iobase)
+ Port_t iobase;
{
int timo;
@@ -3899,7 +3937,7 @@ siocntxwait()
* transmits.
*/
timo = 100000;
- while ((inb(siocniobase + com_lsr) & (LSR_TSRE | LSR_TXRDY))
+ while ((inb(iobase + com_lsr) & (LSR_TSRE | LSR_TXRDY))
!= (LSR_TSRE | LSR_TXRDY) && --timo != 0)
;
}
@@ -3941,23 +3979,23 @@ siocngetspeed(iobase, table)
}
static void
-siocnopen(sp)
+siocnopen(sp, iobase, speed)
struct siocnstate *sp;
+ Port_t iobase;
+ int speed;
{
int divisor;
u_char dlbh;
u_char dlbl;
- Port_t iobase;
/*
* 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.
*/
- iobase = siocniobase;
sp->ier = inb(iobase + com_ier);
outb(iobase + com_ier, 0); /* spltty() doesn't stop siointr() */
- siocntxwait();
+ siocntxwait(iobase);
sp->cfcr = inb(iobase + com_cfcr);
outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
sp->dlbl = inb(iobase + com_dlbl);
@@ -3968,7 +4006,7 @@ siocnopen(sp)
* data input register. This also reduces the effects of the
* UMC8669F bug.
*/
- divisor = ttspeedtab(comdefaultrate, comspeedtab);
+ divisor = ttspeedtab(speed, comspeedtab);
dlbl = divisor & 0xFF;
if (sp->dlbl != dlbl)
outb(iobase + com_dlbl, dlbl);
@@ -3986,16 +4024,14 @@ siocnopen(sp)
}
static void
-siocnclose(sp)
+siocnclose(sp, iobase)
struct siocnstate *sp;
+ Port_t iobase;
{
- Port_t iobase;
-
/*
* Restore the device control registers.
*/
- siocntxwait();
- iobase = siocniobase;
+ siocntxwait(iobase);
outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
if (sp->dlbl != inb(iobase + com_dlbl))
outb(iobase + com_dlbl, sp->dlbl);
@@ -4009,14 +4045,16 @@ siocnclose(sp)
outb(iobase + com_ier, sp->ier);
}
-static void
+#ifdef __i386__
+static
+#endif
+void
siocnprobe(cp)
struct consdev *cp;
{
speed_t boot_speed;
u_char cfcr;
- struct isa_device *dvp;
- int s;
+ int s, unit;
struct siocnstate sp;
/*
@@ -4034,10 +4072,16 @@ siocnprobe(cp)
* don't need to probe.
*/
cp->cn_pri = CN_DEAD;
- for (dvp = isa_devtab_tty; dvp->id_driver != NULL; dvp++)
- if (dvp->id_driver == &siodriver && dvp->id_enabled
- && COM_CONSOLE(dvp)) {
- siocniobase = dvp->id_iobase;
+
+ for (unit = 0; unit < 16; unit++) { /* XXX need to know how many */
+ int flags;
+ if (resource_int_value("sio", unit, "flags", &flags))
+ continue;
+ if (COM_CONSOLE(flags)) {
+ int port;
+ if (resource_int_value("sio", unit, "port", &port))
+ continue;
+ siocniobase = port;
s = spltty();
if (boothowto & RB_SERIAL) {
boot_speed = siocngetspeed(siocniobase,
@@ -4063,26 +4107,119 @@ siocnprobe(cp)
(u_int) COMBRD(comdefaultrate) >> 8);
outb(siocniobase + com_cfcr, cfcr);
- siocnopen(&sp);
+ siocnopen(&sp, siocniobase, comdefaultrate);
splx(s);
- if (!COM_LLCONSOLE(dvp)) {
- cp->cn_dev = makedev(CDEV_MAJOR, dvp->id_unit);
- cp->cn_pri = COM_FORCECONSOLE(dvp)
+ if (!COM_LLCONSOLE(flags)) {
+ cp->cn_dev = makedev(CDEV_MAJOR, unit);
+ cp->cn_pri = COM_FORCECONSOLE(flags)
|| boothowto & RB_SERIAL
? CN_REMOTE : CN_NORMAL;
}
break;
}
+ }
}
-static void
+#ifdef __alpha__
+
+struct consdev siocons = {
+ NULL, NULL, siocngetc, siocncheckc, siocnputc,
+ NULL, makedev(CDEV_MAJOR, 0), CN_NORMAL,
+};
+
+extern struct consdev *cn_tab;
+
+int
+siocnattach(port, speed)
+ int port;
+ int speed;
+{
+ int s;
+ u_char cfcr;
+ struct siocnstate sp;
+
+ siocniobase = port;
+ comdefaultrate = speed;
+
+ s = spltty();
+
+ /*
+ * 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(siocniobase + com_cfcr);
+ outb(siocniobase + com_cfcr, CFCR_DLAB | cfcr);
+ outb(siocniobase + com_dlbl,
+ COMBRD(comdefaultrate) & 0xff);
+ outb(siocniobase + com_dlbh,
+ (u_int) COMBRD(comdefaultrate) >> 8);
+ outb(siocniobase + com_cfcr, cfcr);
+
+ siocnopen(&sp, siocniobase, comdefaultrate);
+ splx(s);
+
+ cn_tab = &siocons;
+ return 0;
+}
+
+int
+siogdbattach(port, speed)
+ int port;
+ int speed;
+{
+ int s;
+ u_char cfcr;
+ struct siocnstate sp;
+
+ siogdbiobase = port;
+ gdbdefaultrate = speed;
+
+ s = spltty();
+
+ /*
+ * 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(siogdbiobase + com_cfcr);
+ outb(siogdbiobase + com_cfcr, CFCR_DLAB | cfcr);
+ outb(siogdbiobase + com_dlbl,
+ COMBRD(gdbdefaultrate) & 0xff);
+ outb(siogdbiobase + com_dlbh,
+ (u_int) COMBRD(gdbdefaultrate) >> 8);
+ outb(siogdbiobase + com_cfcr, cfcr);
+
+ siocnopen(&sp, siogdbiobase, gdbdefaultrate);
+ splx(s);
+
+ return 0;
+}
+
+#endif
+
+#ifdef __i386__
+static
+#endif
+void
siocninit(cp)
struct consdev *cp;
{
comconsole = DEV_TO_UNIT(cp->cn_dev);
}
-static int
+#ifdef __i386__
+static
+#endif
+int
siocncheckc(dev)
dev_t dev;
{
@@ -4093,12 +4230,12 @@ siocncheckc(dev)
iobase = siocniobase;
s = spltty();
- siocnopen(&sp);
+ siocnopen(&sp, iobase, comdefaultrate);
if (inb(iobase + com_lsr) & LSR_RXRDY)
c = inb(iobase + com_data);
else
c = -1;
- siocnclose(&sp);
+ siocnclose(&sp, iobase);
splx(s);
return (c);
}
@@ -4115,11 +4252,11 @@ siocngetc(dev)
iobase = siocniobase;
s = spltty();
- siocnopen(&sp);
+ siocnopen(&sp, iobase, comdefaultrate);
while (!(inb(iobase + com_lsr) & LSR_RXRDY))
;
c = inb(iobase + com_data);
- siocnclose(&sp);
+ siocnclose(&sp, iobase);
splx(s);
return (c);
}
@@ -4133,10 +4270,44 @@ siocnputc(dev, c)
struct siocnstate sp;
s = spltty();
- siocnopen(&sp);
- siocntxwait();
+ siocnopen(&sp, siocniobase, comdefaultrate);
+ siocntxwait(siocniobase);
outb(siocniobase + com_data, c);
- siocnclose(&sp);
+ siocnclose(&sp, siocniobase);
+ splx(s);
+}
+
+int
+siogdbgetc()
+{
+ int c;
+ Port_t iobase;
+ int s;
+ struct siocnstate sp;
+
+ iobase = siogdbiobase;
+ s = spltty();
+ siocnopen(&sp, iobase, gdbdefaultrate);
+ while (!(inb(iobase + com_lsr) & LSR_RXRDY))
+ ;
+ c = inb(iobase + com_data);
+ siocnclose(&sp, iobase);
+ splx(s);
+ return (c);
+}
+
+void
+siogdbputc(c)
+ int c;
+{
+ int s;
+ struct siocnstate sp;
+
+ s = spltty();
+ siocnopen(&sp, siogdbiobase, gdbdefaultrate);
+ siocntxwait(siogdbiobase);
+ outb(siogdbiobase + com_data, c);
+ siocnclose(&sp, siogdbiobase);
splx(s);
}
@@ -4204,7 +4375,6 @@ static void
siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
{
struct pnp_cinfo d;
- struct isa_device *dvp;
if (dev->id_unit >= NSIOTOT)
return;
@@ -4226,9 +4396,7 @@ siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
if (dev->id_driver == NULL) {
dev->id_driver = &siodriver;
- dvp = find_isadev(isa_devtab_tty, &siodriver, 0);
- if (dvp != NULL)
- dev->id_id = dvp->id_id;
+ dev->id_id = isa_compat_nextid();
}
if ((dev->id_alive = sioprobe(dev)) != 0)
@@ -4238,6 +4406,9 @@ siopnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
}
#endif
+CDEV_DRIVER_MODULE(sio, isa, sio_driver, sio_devclass,
+ CDEV_MAJOR, sio_cdevsw, 0, 0);
+
#ifdef PC98
/*
* pc98 local function
@@ -4698,7 +4869,7 @@ pc98_set_baud_rate( struct com_s *com, int count )
}
}
static int
-pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
+pc98_check_if_type(device_t dev, struct siodev *iod)
{
int irr, io, if_type, tmp;
static short irq_tab[2][8] = {
@@ -4706,13 +4877,13 @@ pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
{ 3, 10, 12, 13, 5, 6, 9, -1}
};
- iod->if_type = if_type = (dev->id_flags >> 24) & 0xff;
+ iod->if_type = if_type = (isa_get_flags(dev) >> 24) & 0xff;
if ((if_type < 0 || if_type > COM_IF_END1) &&
(if_type < 0x10 || if_type > COM_IF_END2))
return(-1);
if_type &= 0x0f;
iod->irq = 0;
- io = dev->id_iobase & 0xff00;
+ io = isa_get_port(dev) & 0xff00;
if (IS_8251(iod->if_type)) {
if (PC98SIO_func_port(if_type) != -1) {
@@ -4744,7 +4915,7 @@ pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
}
} else {
tmp = inb( iod->mod ) & if_8251_type[if_type].irr_mask;
- if ((dev->id_iobase & 0xff) == IO_COM2)
+ if ((isa_get_port(dev) & 0xff) == IO_COM2)
iod->irq = irq_tab[0][tmp];
else
iod->irq = irq_tab[1][tmp];
@@ -4756,7 +4927,7 @@ pc98_check_if_type(struct isa_device *dev, struct siodev *iod)
#endif
if (irr != -1) {
tmp = inb(io | irr);
- if (dev->id_iobase & 0x01) /* XXX depend on RSB-384 */
+ 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];
diff --git a/sys/pc98/pc98/syscons.c b/sys/pc98/pc98/syscons.c
index 0e99c5f..98bb1db 100644
--- a/sys/pc98/pc98/syscons.c
+++ b/sys/pc98/pc98/syscons.c
@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: syscons.c,v 1.114 1999/03/10 14:51:53 kato Exp $
+ * $Id: syscons.c,v 1.115 1999/04/04 02:53:08 kato Exp $
*/
#include "sc.h"
@@ -33,7 +33,6 @@
#include "apm.h"
#include "opt_ddb.h"
#include "opt_devfs.h"
-#include "opt_vesa.h"
#include "opt_vm86.h"
#include "opt_syscons.h"
@@ -42,6 +41,8 @@
#include <sys/systm.h>
#include <sys/reboot.h>
#include <sys/conf.h>
+#include <sys/module.h>
+#include <sys/bus.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/tty.h>
@@ -79,6 +80,7 @@
#include <i386/isa/isa_device.h>
#include <i386/isa/timerreg.h>
#include <pc98/pc98/syscons.h>
+#include <isa/isavar.h>
#else
#include <dev/fb/vgareg.h>
#include <dev/syscons/syscons.h>
@@ -282,10 +284,10 @@ static const int nsccons = MAXCONS+2;
(*kbdsw[(kbd)->kb_index]->poll)((kbd), (on))
/* prototypes */
-static int scattach(struct isa_device *dev);
+static int scattach(device_t dev);
static kbd_callback_func_t sckbdevent;
static int scparam(struct tty *tp, struct termios *t);
-static int scprobe(struct isa_device *dev);
+static int scprobe(device_t dev);
static int scvidprobe(int unit, int flags, int cons);
static int sckbdprobe(int unit, int flags, int cons);
static void scstart(struct tty *tp);
@@ -357,10 +359,23 @@ static cn_putc_t sccnputc;
CONS_DRIVER(sc, sccnprobe, sccninit, sccngetc, sccncheckc, sccnputc);
-struct isa_driver scdriver = {
- scprobe, scattach, "sc", 1
+devclass_t sc_devclass;
+
+static device_method_t sc_methods[] = {
+ DEVMETHOD(device_probe, scprobe),
+ DEVMETHOD(device_attach, scattach),
+ { 0, 0 }
+};
+
+static driver_t sc_driver = {
+ "sc",
+ sc_methods,
+ DRIVER_TYPE_TTY,
+ 1, /* XXX */
};
+DRIVER_MODULE(sc, isa, sc_driver, sc_devclass, 0, 0);
+
static d_open_t scopen;
static d_close_t scclose;
static d_read_t scread;
@@ -511,15 +526,20 @@ move_crsr(scr_stat *scp, int x, int y)
}
static int
-scprobe(struct isa_device *dev)
+scprobe(device_t dev)
{
- if (!scvidprobe(dev->id_unit, dev->id_flags, FALSE)) {
+ int unit = device_get_unit(dev);
+ int flags = isa_get_flags(dev);
+
+ device_set_desc(dev, "System console");
+
+ if (!scvidprobe(unit, flags, FALSE)) {
if (bootverbose)
- printf("sc%d: no video adapter is found.\n", dev->id_unit);
- return (0);
+ printf("sc%d: no video adapter is found.\n", unit);
+ return ENXIO;
}
- return ((sckbdprobe(dev->id_unit, dev->id_flags, FALSE)) ? -1 : 0);
+ return ((sckbdprobe(unit, flags, FALSE)) ? 0 : ENXIO);
}
/* probe video adapters, return TRUE if found */
@@ -583,7 +603,7 @@ scresume(void *dummy)
#endif
static int
-scattach(struct isa_device *dev)
+scattach(device_t dev)
{
scr_stat *scp;
#if defined(VESA) && defined(VM86)
@@ -596,7 +616,7 @@ scattach(struct isa_device *dev)
scinit();
scp = console[0];
- sc_flags = dev->id_flags;
+ sc_flags = isa_get_flags(dev);
if (!ISFONTAVAIL(scp->adp->va_flags))
sc_flags &= ~CHAR_CURSOR;
@@ -646,14 +666,14 @@ scattach(struct isa_device *dev)
update_kbd_state(scp->status, LOCK_MASK);
if (bootverbose) {
- printf("sc%d:", dev->id_unit);
+ printf("sc%d:", device_get_unit(dev));
if (adapter >= 0)
printf(" fb%d", adapter);
if (keyboard >= 0)
printf(" kbd%d", keyboard);
printf("\n");
}
- printf("sc%d: ", dev->id_unit);
+ printf("sc%d: ", device_get_unit(dev));
switch(scp->adp->va_type) {
#ifdef PC98
case KD_PC98:
@@ -1923,6 +1943,7 @@ scmousestart(struct tty *tp)
static void
sccnprobe(struct consdev *cp)
{
+#if 0
struct isa_device *dvp;
/*
@@ -1939,6 +1960,13 @@ sccnprobe(struct consdev *cp)
return;
}
sckbdprobe(dvp->id_unit, dvp->id_flags, TRUE);
+#else
+ if (!scvidprobe(0, 0, TRUE)) {
+ cp->cn_pri = CN_DEAD;
+ return;
+ }
+ sckbdprobe(0, 0, TRUE);
+#endif
/* initialize required fields */
cp->cn_dev = makedev(CDEV_MAJOR, SC_CONSOLE);
diff --git a/sys/pc98/pc98/wd.c b/sys/pc98/pc98/wd.c
index 0fc116a..6534255 100644
--- a/sys/pc98/pc98/wd.c
+++ b/sys/pc98/pc98/wd.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
- * $Id: wd.c,v 1.76 1999/03/25 08:29:32 kato Exp $
+ * $Id: wd.c,v 1.77 1999/04/03 15:51:54 kato Exp $
*/
/* TODO:
@@ -64,17 +64,16 @@
#if NWDC > 0
-#include "opt_atapi.h"
#include "opt_devfs.h"
#include "opt_hw_wdog.h"
#include "opt_ide_delay.h"
-#include "opt_wd.h"
#include <sys/param.h>
#include <sys/dkbad.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/conf.h>
+#include <sys/bus.h>
#include <sys/disklabel.h>
#include <sys/diskslice.h>
#include <sys/buf.h>
@@ -505,10 +504,10 @@ wdattach(struct isa_device *dvp)
#if defined(DEVFS)
int mynor;
#endif
- u_int unit, lunit;
- struct isa_device *wdup;
+ int unit, lunit, flags, i;
struct disk *du;
struct wdparams *wp;
+ static char buf[] = "wdcXXX";
dvp->id_intr = wdintr;
@@ -528,16 +527,17 @@ wdattach(struct isa_device *dvp)
bufq_init(&wdtab[dvp->id_unit].controller_queue);
#endif
- for (wdup = isa_biotab_wdc; wdup->id_driver != 0; wdup++) {
- if (!old_epson_note) {
- if (wdup->id_iobase != dvp->id_iobase)
- continue;
- }
- lunit = wdup->id_unit;
- if (lunit >= NWD)
+ sprintf(buf, "wdc%d", dvp->id_unit);
+ for (i = resource_query_string(-1, "at", buf);
+ i != -1;
+ i = resource_query_string(i, "at", buf)) {
+ if (strcmp(resource_query_name(i), "wd"))
+ /* Avoid a bit of foot shooting. */
continue;
- unit = wdup->id_physid;
+ lunit = resource_query_unit(i);
+ if (lunit >= NWD)
+ continue;
#ifdef PC98
if ((lunit%2)!=0) {
if ((PC98_SYSTEM_PARAMETER(0x457) & 0x40)==0) {
@@ -546,6 +546,11 @@ wdattach(struct isa_device *dvp)
}
#endif
+ if (resource_int_value("wd", lunit, "drive", &unit) != 0)
+ continue;
+ if (resource_int_value("wd", lunit, "flags", &flags) != 0)
+ flags = 0;
+
du = malloc(sizeof *du, M_TEMP, M_NOWAIT);
if (du == NULL)
continue;
@@ -571,7 +576,7 @@ wdattach(struct isa_device *dvp)
* Use the individual device flags or the controller
* flags.
*/
- du->cfg_flags = wdup->id_flags |
+ du->cfg_flags = flags |
((dvp->id_flags) >> (16 * unit));
if (wdgetctlr(du) == 0) {
OpenPOWER on IntegriCloud