From c55a92c639a229963002d51eae4db058bb4f2c55 Mon Sep 17 00:00:00 2001 From: KATO Takenori Date: Sun, 18 Apr 1999 14:42:20 +0000 Subject: 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 --- sys/conf/Makefile.pc98 | 60 +- sys/conf/files.pc98 | 41 +- sys/conf/options.pc98 | 9 +- sys/pc98/cbus/cbus_dma.c | 560 ++++++++++++++++++ sys/pc98/cbus/fdc.c | 1365 +++++++++++++++++++++++-------------------- sys/pc98/cbus/gdc.c | 76 +-- sys/pc98/cbus/pckbd.c | 85 +-- sys/pc98/cbus/sio.c | 587 ++++++++++++------- sys/pc98/conf/GENERIC | 64 +- sys/pc98/conf/GENERIC98 | 64 +- sys/pc98/conf/Makefile.pc98 | 60 +- sys/pc98/conf/files.pc98 | 41 +- sys/pc98/conf/options.pc98 | 9 +- sys/pc98/i386/machdep.c | 27 +- sys/pc98/i386/userconfig.c | 129 +++- sys/pc98/pc98/fd.c | 1365 +++++++++++++++++++++++-------------------- sys/pc98/pc98/if_ed.c | 7 +- sys/pc98/pc98/isa_dma.c | 560 ++++++++++++++++++ sys/pc98/pc98/machdep.c | 27 +- sys/pc98/pc98/npx.c | 179 ++++-- sys/pc98/pc98/pc98gdc.c | 76 +-- sys/pc98/pc98/pc98kbd.c | 85 +-- sys/pc98/pc98/sio.c | 587 ++++++++++++------- sys/pc98/pc98/syscons.c | 58 +- sys/pc98/pc98/wd.c | 33 +- 25 files changed, 3966 insertions(+), 2188 deletions(-) create mode 100644 sys/pc98/cbus/cbus_dma.c create mode 100644 sys/pc98/pc98/isa_dma.c (limited to 'sys') diff --git a/sys/conf/Makefile.pc98 b/sys/conf/Makefile.pc98 index f9c671711045..78ffe973e467 100644 --- a/sys/conf/Makefile.pc98 +++ b/sys/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/conf/files.pc98 b/sys/conf/files.pc98 index b85515cd140d..65d2f094b13d 100644 --- a/sys/conf/files.pc98 +++ b/sys/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/conf/options.pc98 b/sys/conf/options.pc98 index 9e45a0bc89e9..9c61ad2ededd 100644 --- a/sys/conf/options.pc98 +++ b/sys/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/cbus/cbus_dma.c b/sys/pc98/cbus/cbus_dma.c new file mode 100644 index 000000000000..6599b05a1971 --- /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 +#include +#include +#include +#include +#include +#ifdef APIC_IO +#include +#endif /* APIC_IO */ +#include +#include +#include +#include +#include +#ifdef PC98 +#include +#else +#include +#endif +#include + +#include + +#include "pnp.h" +#if NPNP > 0 +#include +#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 c70dc56775ea..7d6c8bb16f13 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 #include #include +#include +#include #include -#include -#include -#include #include -#include #include +#include #include +#include #include #include + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef DEVFS +#include +#endif /* DEVFS */ + +#include #ifdef PC98 #include #include #include -#include +#include #include #else #include -#include +#include #include -#include #endif #include -#include -#ifdef DEVFS -#include -#endif /* DEVFS */ +#include /* 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 6b4ac09e339a..7f4570a2b608 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 #include - -#include +#include #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 731f463e084c..a9d44f72325b 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 #include #include +#include #include #include -#include #include +#include +#include +#include #include @@ -51,6 +54,9 @@ #include #include +#include +#include + #ifdef __i386__ #include #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 962d4f9d3db9..94adb71c5178 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 #include #include +#include #include #include #include @@ -148,28 +150,32 @@ #include #include #include +#include +#include +#include #ifdef DEVFS #include #endif #include -#include -#include -#ifndef SMP -#include -#endif - #ifdef PC98 #include #include -#include #include #else -#include +#include +#endif +#include +#include + +#include +#include +#ifndef SMP +#include #endif -#include -#include -#include +#include + +#include #ifdef COM_ESP #include @@ -179,6 +185,8 @@ #include #endif +#if 0 + #include "card.h" #if NCARD > 0 #include @@ -190,6 +198,13 @@ #include #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 1bde43338c48..2398f2fb6983 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 1bde43338c48..2398f2fb6983 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 f9c671711045..78ffe973e467 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 b85515cd140d..65d2f094b13d 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 9e45a0bc89e9..9c61ad2ededd 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 812c577f9736..61950dabf36b 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 #include #include +#include #ifdef SYSVSHM #include @@ -125,7 +126,9 @@ #include #endif +#ifdef OLD_BUS_ARCH #include +#endif #include #ifdef PC98 #include @@ -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 1bb9377d5181..a74a5294cb10 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 #include #include +#include #include #include #include + #include #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 c70dc56775ea..7d6c8bb16f13 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 #include #include +#include +#include #include -#include -#include -#include #include -#include #include +#include #include +#include #include #include + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef DEVFS +#include +#endif /* DEVFS */ + +#include #ifdef PC98 #include #include #include -#include +#include #include #else #include -#include +#include #include -#include #endif #include -#include -#ifdef DEVFS -#include -#endif /* DEVFS */ +#include /* 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 b71f68e83f52..4358562948f2 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 000000000000..6599b05a1971 --- /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 +#include +#include +#include +#include +#include +#ifdef APIC_IO +#include +#endif /* APIC_IO */ +#include +#include +#include +#include +#include +#ifdef PC98 +#include +#else +#include +#endif +#include + +#include + +#include "pnp.h" +#if NPNP > 0 +#include +#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 812c577f9736..61950dabf36b 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 #include #include +#include #ifdef SYSVSHM #include @@ -125,7 +126,9 @@ #include #endif +#ifdef OLD_BUS_ARCH #include +#endif #include #ifdef PC98 #include @@ -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 a26ff4b3558d..c17b50a0a7db 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 #include +#include #include #include +#include #include #include +#include +#include #ifdef NPX_DEBUG #include #endif @@ -65,6 +69,7 @@ #ifndef SMP #include #endif +#include #include #include @@ -77,7 +82,6 @@ #include #endif #endif -#include /* * 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 6b4ac09e339a..7f4570a2b608 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 #include - -#include +#include #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 731f463e084c..a9d44f72325b 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 #include #include +#include #include #include -#include #include +#include +#include +#include #include @@ -51,6 +54,9 @@ #include #include +#include +#include + #ifdef __i386__ #include #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 962d4f9d3db9..94adb71c5178 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 #include #include +#include #include #include #include @@ -148,28 +150,32 @@ #include #include #include +#include +#include +#include #ifdef DEVFS #include #endif #include -#include -#include -#ifndef SMP -#include -#endif - #ifdef PC98 #include #include -#include #include #else -#include +#include +#endif +#include +#include + +#include +#include +#ifndef SMP +#include #endif -#include -#include -#include +#include + +#include #ifdef COM_ESP #include @@ -179,6 +185,8 @@ #include #endif +#if 0 + #include "card.h" #if NCARD > 0 #include @@ -190,6 +198,13 @@ #include #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 0e99c5f7d95f..98bb1db854e1 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 #include #include +#include +#include #include #include #include @@ -79,6 +80,7 @@ #include #include #include +#include #else #include #include @@ -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 0fc116aaca94..653425544ab5 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 #include #include #include #include +#include #include #include #include @@ -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) { -- cgit v1.2.3