summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1999-04-16 21:22:55 +0000
committerpeter <peter@FreeBSD.org>1999-04-16 21:22:55 +0000
commit087d4857e56f150a8f549600150404f273efb895 (patch)
treecf4e27432c59d956f4e5784207180115ee8fef9d
parentc5fe612b8411a32a8e6e426fc1a70cba0cca3d31 (diff)
downloadFreeBSD-src-087d4857e56f150a8f549600150404f273efb895.zip
FreeBSD-src-087d4857e56f150a8f549600150404f273efb895.tar.gz
Bring the 'new-bus' to the i386. This extensively changes the way the
i386 platform boots, it is no longer ISA-centric, and is fully dynamic. Most old drivers compile and run without modification via 'compatability shims' to enable a smoother transition. eisa, isapnp and pccard* are not yet using the new resource manager. Once fully converted, all drivers will be loadable, including PCI and ISA. (Some other changes appear to have snuck in, including a port of Soren's ATA driver to the Alpha. Soren, back this out if you need to.) This is a checkpoint of work-in-progress, but is quite functional. The bulk of the work was done over the last few years by Doug Rabson and Garrett Wollman. Approved by: core
-rw-r--r--sys/alpha/alpha/autoconf.c4
-rw-r--r--sys/alpha/conf/files.alpha12
-rw-r--r--sys/alpha/include/chipset.h9
-rw-r--r--sys/alpha/include/cpuconf.h1
-rw-r--r--sys/alpha/include/cpufunc.h36
-rw-r--r--sys/alpha/isa/isa.c89
-rw-r--r--sys/alpha/isa/isavar.h39
-rw-r--r--sys/alpha/pci/apecs.c66
-rw-r--r--sys/alpha/pci/apecs_pci.c73
-rw-r--r--sys/alpha/pci/cia.c15
-rw-r--r--sys/alpha/pci/cia_pci.c73
-rw-r--r--sys/alpha/pci/lca.c50
-rw-r--r--sys/alpha/pci/lca_pci.c73
-rw-r--r--sys/alpha/pci/pcibus.c78
-rw-r--r--sys/alpha/tc/tc.c4
-rw-r--r--sys/alpha/tc/tcasic.c3
-rw-r--r--sys/alpha/tlsb/dwlpx.c4
-rw-r--r--sys/amd64/amd64/autoconf.c28
-rw-r--r--sys/amd64/amd64/exception.S6
-rw-r--r--sys/amd64/amd64/exception.s6
-rw-r--r--sys/amd64/amd64/fpu.c159
-rw-r--r--sys/amd64/amd64/legacy.c409
-rw-r--r--sys/amd64/amd64/machdep.c18
-rw-r--r--sys/amd64/amd64/nexus.c409
-rw-r--r--sys/amd64/conf/GENERIC24
-rw-r--r--sys/amd64/isa/intr_machdep.c4
-rw-r--r--sys/amd64/isa/isa.c1462
-rw-r--r--sys/amd64/isa/isa_dma.c510
-rw-r--r--sys/amd64/isa/isa_dma.h51
-rw-r--r--sys/amd64/isa/nmi.c4
-rw-r--r--sys/amd64/isa/npx.c159
-rw-r--r--sys/boot/alpha/boot1/boot1.c54
-rw-r--r--sys/boot/alpha/libalpha/prom.c4
-rw-r--r--sys/boot/alpha/libalpha/start.S7
-rw-r--r--sys/boot/alpha/netboot/Makefile1
-rw-r--r--sys/boot/common/bootstrap.h6
-rw-r--r--sys/boot/ofw/libofw/ofw_console.c4
-rw-r--r--sys/conf/Makefile.i3864
-rw-r--r--sys/conf/Makefile.powerpc4
-rw-r--r--sys/conf/NOTES16
-rw-r--r--sys/conf/files15
-rw-r--r--sys/conf/files.alpha12
-rw-r--r--sys/conf/files.i38617
-rw-r--r--sys/dev/aha/aha_isa.c7
-rw-r--r--sys/dev/ata/ata-all.c34
-rw-r--r--sys/dev/ata/ata-disk.c10
-rw-r--r--sys/dev/ata/ata-dma.c14
-rw-r--r--sys/dev/ata/atapi-all.c10
-rw-r--r--sys/dev/atkbdc/atkbd.c19
-rw-r--r--sys/dev/atkbdc/atkbd_atkbdc.c15
-rw-r--r--sys/dev/atkbdc/atkbd_isa.c15
-rw-r--r--sys/dev/atkbdc/psm.c9
-rw-r--r--sys/dev/cs/if_cs.c7
-rw-r--r--sys/dev/ed/if_ed.c7
-rw-r--r--sys/dev/fdc/fdc.c1139
-rw-r--r--sys/dev/fxp/if_fxp.c186
-rw-r--r--sys/dev/fxp/if_fxpvar.h5
-rw-r--r--sys/dev/kbd/atkbd.c19
-rw-r--r--sys/dev/pci/pci.c653
-rw-r--r--sys/dev/pci/pci_if.m44
-rw-r--r--sys/dev/pci/pcireg.h4
-rw-r--r--sys/dev/pci/pcivar.h79
-rw-r--r--sys/dev/rp/rp.c8
-rw-r--r--sys/dev/sio/sio.c55
-rw-r--r--sys/dev/syscons/syscons.c10
-rw-r--r--sys/dev/usb/ohci.c10
-rw-r--r--sys/dev/usb/ohci_pci.c154
-rw-r--r--sys/dev/usb/ohcivar.h3
-rw-r--r--sys/dev/usb/ucom.c7
-rw-r--r--sys/dev/usb/ugen.c7
-rw-r--r--sys/dev/usb/uhci.c13
-rw-r--r--sys/dev/usb/uhci_pci.c166
-rw-r--r--sys/dev/usb/uhcivar.h3
-rw-r--r--sys/dev/usb/uhid.c7
-rw-r--r--sys/dev/usb/uhub.c24
-rw-r--r--sys/dev/usb/ulpt.c7
-rw-r--r--sys/dev/usb/umodem.c7
-rw-r--r--sys/dev/usb/ums.c6
-rw-r--r--sys/dev/usb/usb.c3
-rw-r--r--sys/dev/usb/usb_if.m9
-rw-r--r--sys/dev/usb/usb_port.h2
-rw-r--r--sys/dev/usb/usbdi.c25
-rw-r--r--sys/dev/usb/usbdi.h1
-rw-r--r--sys/i386/apm/apm.c70
-rw-r--r--sys/i386/bios/apm.c70
-rw-r--r--sys/i386/conf/GENERIC24
-rw-r--r--sys/i386/conf/LINT16
-rw-r--r--sys/i386/conf/Makefile.i3864
-rw-r--r--sys/i386/conf/NOTES16
-rw-r--r--sys/i386/conf/files.i38617
-rw-r--r--sys/i386/i386/autoconf.c28
-rw-r--r--sys/i386/i386/exception.s6
-rw-r--r--sys/i386/i386/legacy.c409
-rw-r--r--sys/i386/i386/machdep.c18
-rw-r--r--sys/i386/i386/nexus.c409
-rw-r--r--sys/i386/i386/userconfig.c121
-rw-r--r--sys/i386/include/asnames.h4
-rw-r--r--sys/i386/isa/aha_isa.c7
-rw-r--r--sys/i386/isa/fd.c1139
-rw-r--r--sys/i386/isa/fdc.h6
-rw-r--r--sys/i386/isa/if_cs.c7
-rw-r--r--sys/i386/isa/if_ed.c7
-rw-r--r--sys/i386/isa/intr_machdep.c4
-rw-r--r--sys/i386/isa/isa.c1462
-rw-r--r--sys/i386/isa/isa_compat.c255
-rw-r--r--sys/i386/isa/isa_compat.h378
-rw-r--r--sys/i386/isa/isa_device.h29
-rw-r--r--sys/i386/isa/isa_dma.c510
-rw-r--r--sys/i386/isa/isa_dma.h51
-rw-r--r--sys/i386/isa/nmi.c4
-rw-r--r--sys/i386/isa/npx.c159
-rw-r--r--sys/i386/isa/rp.c8
-rw-r--r--sys/i386/isa/snd/sound.c5
-rw-r--r--sys/i386/isa/sound/ad1848.c5
-rw-r--r--sys/i386/isa/wd.c25
-rw-r--r--sys/isa/atkbd_isa.c15
-rw-r--r--sys/isa/fd.c1139
-rw-r--r--sys/isa/fdc.h6
-rw-r--r--sys/isa/isavar.h7
-rw-r--r--sys/isa/psm.c9
-rw-r--r--sys/isa/sio.c55
-rw-r--r--sys/isa/syscons_isa.c5
-rw-r--r--sys/isa/vga_isa.c13
-rw-r--r--sys/kern/bus_if.m12
-rw-r--r--sys/kern/makedevops.pl2
-rw-r--r--sys/kern/subr_bus.c386
-rw-r--r--sys/kern/subr_rman.c39
-rw-r--r--sys/net/if.c35
-rw-r--r--sys/net/if_media.c15
-rw-r--r--sys/net/if_media.h5
-rw-r--r--sys/net/if_var.h3
-rw-r--r--sys/pci/ide_pci.c5
-rw-r--r--sys/pci/if_fxp.c186
-rw-r--r--sys/pci/if_fxpvar.h5
-rw-r--r--sys/pci/if_pn.c10
-rw-r--r--sys/pci/if_xl.c12
-rw-r--r--sys/pci/ohci_pci.c154
-rw-r--r--sys/pci/pci.c653
-rw-r--r--sys/pci/pci_compat.c192
-rw-r--r--sys/pci/pci_if.m44
-rw-r--r--sys/pci/pcireg.h4
-rw-r--r--sys/pci/pcisupport.c824
-rw-r--r--sys/pci/pcivar.h79
-rw-r--r--sys/pci/uhci_pci.c166
-rw-r--r--sys/sys/bus.h10
-rw-r--r--sys/sys/bus_private.h3
-rw-r--r--sys/sys/rman.h11
147 files changed, 10870 insertions, 5332 deletions
diff --git a/sys/alpha/alpha/autoconf.c b/sys/alpha/alpha/autoconf.c
index da47473..e5489c6 100644
--- a/sys/alpha/alpha/autoconf.c
+++ b/sys/alpha/alpha/autoconf.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: autoconf.c,v 1.14 1999/03/12 14:44:46 gallatin Exp $
+ * $Id: autoconf.c,v 1.15 1999/03/28 17:33:38 dfr Exp $
*/
#include "opt_bootp.h"
@@ -190,7 +190,7 @@ configure(void *dummy)
if((hwrpb->rpb_type != ST_DEC_3000_300) &&
(hwrpb->rpb_type != ST_DEC_3000_500)){
- pci_configure();
+ /* pci_configure(); */
/*
* Probe ISA devices after everything.
diff --git a/sys/alpha/conf/files.alpha b/sys/alpha/conf/files.alpha
index 6f747e3..d0f4003 100644
--- a/sys/alpha/conf/files.alpha
+++ b/sys/alpha/conf/files.alpha
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.alpha,v 1.16 1999/01/23 16:53:26 dfr Exp $
+# $Id: files.alpha,v 1.17 1999/03/10 10:36:50 yokota Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -112,10 +112,13 @@ mcclock_if.h standard \
no-obj no-implicit-rule before-depend \
clean "mcclock_if.h"
alpha/pci/cia.c optional cia
+alpha/pci/cia_pci.c optional cia
alpha/pci/pci_eb164_intr.s optional cia
alpha/pci/apecs.c optional apecs
+alpha/pci/apecs_pci.c optional apecs
alpha/pci/pci_eb64plus_intr.s optional apecs
alpha/pci/lca.c optional lca
+alpha/pci/lca_pci.c optional lca
alpha/pci/pcibus.c optional pci
alpha/isa/isa.c optional isa
alpha/isa/mcclock_isa.c optional isa
@@ -157,3 +160,10 @@ dev/syscons/syscons.c optional sc device-driver
dev/syscons/scvidctl.c optional sc device-driver
isa/syscons_isa.c optional sc device-driver
isa/psm.c optional psm device-driver
+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
+dev/ata/ata-disk.c optional atadisk device-driver
+dev/ata/atapi-cd.c optional atapicd device-driver
+dev/ata/atapi-fd.c optional atapifd device-driver
+dev/ata/atapi-tape.c optional atapist device-driver
diff --git a/sys/alpha/include/chipset.h b/sys/alpha/include/chipset.h
index f7a61be..66f59bb 100644
--- a/sys/alpha/include/chipset.h
+++ b/sys/alpha/include/chipset.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: chipset.h,v 1.5 1998/10/06 14:18:39 dfr Exp $
+ * $Id: chipset.h,v 1.6 1998/11/15 18:25:16 dfr Exp $
*/
#ifndef _MACHINE_CHIPSET_H_
@@ -100,13 +100,6 @@ typedef struct alpha_chipset {
*/
alpha_chipset_read_hae_t* read_hae;
alpha_chipset_write_hae_t* write_hae;
-
- /*
- * PCI interrupt device.
- * (XXX hack until I change pci code to use new
- * device framework.)
- */
- void* intrdev;
} alpha_chipset_t;
extern alpha_chipset_t chipset;
diff --git a/sys/alpha/include/cpuconf.h b/sys/alpha/include/cpuconf.h
index 6bddc82..1965a5a 100644
--- a/sys/alpha/include/cpuconf.h
+++ b/sys/alpha/include/cpuconf.h
@@ -73,6 +73,7 @@ extern struct platform {
void (*pci_intr_map) __P((void *));
void (*pci_intr_disable) __P((int));
void (*pci_intr_enable) __P((int));
+ int (*pci_setup_ide_intr) __P((int chan, void (*fn)(void*), void *arg));
} platform;
/*
diff --git a/sys/alpha/include/cpufunc.h b/sys/alpha/include/cpufunc.h
index bc4ffe3..8326970 100644
--- a/sys/alpha/include/cpufunc.h
+++ b/sys/alpha/include/cpufunc.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cpufunc.h,v 1.2 1998/07/22 08:25:39 dfr Exp $
+ * $Id: cpufunc.h,v 1.3 1998/08/17 08:21:31 dfr Exp $
*/
#ifndef _MACHINE_CPUFUNC_H_
@@ -59,11 +59,45 @@ breakpoint(void)
#define writel(pa,v) chipset.writel(pa,v)
/*
+ * Bulk i/o (for IDE driver).
+ */
+static __inline void insw(u_int32_t port, void *buffer, size_t count)
+{
+ u_int16_t *p = (u_int16_t *) buffer;
+ while (count--)
+ *p++ = inw(port);
+}
+
+static __inline void insl(u_int32_t port, void *buffer, size_t count)
+{
+ u_int32_t *p = (u_int32_t *) buffer;
+ while (count--)
+ *p++ = inl(port);
+}
+
+static __inline void outsw(u_int32_t port, const void *buffer, size_t count)
+{
+ const u_int16_t *p = (const u_int16_t *) buffer;
+ while (count--)
+ outw(port, *p++);
+}
+
+static __inline void outsl(u_int32_t port, const void *buffer, size_t count)
+{
+ const u_int32_t *p = (const u_int32_t *) buffer;
+ while (count--)
+ outl(port, *p++);
+}
+
+/*
* String version of IO memory access ops:
*/
extern void memcpy_fromio(void *, u_int32_t, size_t);
extern void memcpy_toio(u_int32_t, void *, size_t);
+extern void memcpy_io(u_int32_t, u_int32_t, size_t);
extern void memset_io(u_int32_t, int, size_t);
+extern void memsetw(void *, int, size_t);
+extern void memsetw_io(u_int32_t, int, size_t);
#endif /* KERNEL */
diff --git a/sys/alpha/isa/isa.c b/sys/alpha/isa/isa.c
index 56df551..5b6b54e 100644
--- a/sys/alpha/isa/isa.c
+++ b/sys/alpha/isa/isa.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: isa.c,v 1.8 1998/11/28 09:55:16 dfr Exp $
+ * $Id: isa.c,v 1.9 1999/01/23 16:53:27 dfr Exp $
*/
#include <sys/param.h>
@@ -31,11 +31,13 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
+#include <machine/bus.h>
#include <sys/malloc.h>
#include <sys/rman.h>
#include <isa/isareg.h>
#include <isa/isavar.h>
+#include <alpha/isa/isavar.h>
#include <machine/intr.h>
#include <machine/intrcnt.h>
#include <machine/resource.h>
@@ -78,10 +80,6 @@ static struct resource *isa_alloc_resource(device_t bus, device_t child,
u_long count, u_int flags);
static int isa_release_resource(device_t bus, device_t child,
int type, int rid, struct resource *r);
-static int isa_setup_intr(device_t dev, device_t child, struct resource *irq,
- driver_intr_t *intr, void *arg, void **cookiep);
-static int isa_teardown_intr(device_t dev, device_t child,
- struct resource *irq, void *cookie);
static device_method_t isa_methods[] = {
/* Device interface */
@@ -139,7 +137,7 @@ isa_add_device(device_t dev, const char *name, int unit)
idev->id_portsize[0] = 0;
idev->id_portsize[1] = 0;
- if (resource_int_value(name, unit, "iomem", &t) == 0)
+ if (resource_int_value(name, unit, "maddr", &t) == 0)
idev->id_maddr[0] = t;
else
idev->id_maddr[0] = 0;
@@ -236,6 +234,8 @@ isa_probe(device_t dev)
{
int i;
+ device_set_desc(dev, "ISA bus");
+
/*
* Add all devices configured to be attached to isa0.
*/
@@ -256,14 +256,7 @@ isa_probe(device_t dev)
resource_query_unit(i));
}
- isa_irq_rman.rm_start = 0;
- isa_irq_rman.rm_end = 15;
- isa_irq_rman.rm_type = RMAN_ARRAY;
- isa_irq_rman.rm_descr = "ISA Interrupt request lines";
- if (rman_init(&isa_irq_rman)
- || rman_manage_region(&isa_irq_rman, 0, 1)
- || rman_manage_region(&isa_irq_rman, 3, 15))
- panic("isa_probe isa_irq_rman");
+ isa_init_intr();
return 0;
}
@@ -276,13 +269,6 @@ isa_attach(device_t dev)
if (bootverbose)
printf("isa_attach: mask=%04x\n", isa_irq_mask());
- /* mask all isa interrupts */
- outb(IO_ICU1+1, 0xff);
- outb(IO_ICU2+1, 0xff);
-
- /* make sure chaining irq is enabled */
- isa_intr_enable(2);
-
/*
* Arrange for bus_generic_attach(dev) to be called later.
*/
@@ -340,12 +326,14 @@ isa_print_child(device_t bus, device_t dev)
printf("-%#x", (u_int)(id->id_maddr[1]
+ id->id_msize[1] - 1));
}
+#if 0
if (id->id_irq[0] >= 0 && id->id_irq[1] >= 0)
printf(" irqs %d and %d", id->id_irq[0], id->id_irq[1]);
else if (id->id_irq[0] >= 0)
printf(" irq %d", id->id_irq[0]);
else if (id->id_irq[1] >= 0)
printf(" irq %d", id->id_irq[1]);
+#endif
if (id->id_drq[0] >= 0 && id->id_drq[1] >= 0)
printf(" drqs %d and %d", id->id_drq[0], id->id_drq[1]);
else if (id->id_drq[0] >= 0)
@@ -406,8 +394,10 @@ isa_read_ivar(device_t bus, device_t dev,
case ISA_IVAR_FLAGS:
*result = idev->id_flags;
break;
+ default:
+ return (ENOENT);
}
- return ENOENT;
+ return (0);
}
static int
@@ -462,6 +452,43 @@ isa_write_ivar(device_t bus, device_t dev,
return (0);
}
+void isa_init_intr(void)
+{
+ static int initted = 0;
+
+ if (initted) return;
+ initted = 1;
+
+ isa_irq_rman.rm_start = 0;
+ isa_irq_rman.rm_end = 15;
+ isa_irq_rman.rm_type = RMAN_ARRAY;
+ isa_irq_rman.rm_descr = "ISA Interrupt request lines";
+ if (rman_init(&isa_irq_rman)
+ || rman_manage_region(&isa_irq_rman, 0, 1)
+ || rman_manage_region(&isa_irq_rman, 3, 15))
+ panic("isa_probe isa_irq_rman");
+
+ /* mask all isa interrupts */
+ outb(IO_ICU1+1, 0xff);
+ outb(IO_ICU2+1, 0xff);
+
+ /* make sure chaining irq is enabled */
+ isa_intr_enable(2);
+}
+
+struct resource *
+isa_alloc_intr(device_t bus, device_t child, int irq)
+{
+ return rman_reserve_resource(&isa_irq_rman, irq, irq, 1,
+ 0, child);
+}
+
+int
+isa_release_intr(device_t bus, device_t child, struct resource *r)
+{
+ return rman_release_resource(r);
+}
+
/*
* This implementation simply passes the request up to the parent
* bus, which in our case is the pci chipset device, substituting any
@@ -502,7 +529,7 @@ isa_alloc_resource(device_t bus, device_t child, int type, int *rid,
* The hack implementation of intr_create() passes a
* NULL child device.
*/
- if (isdefault && (id == NULL || id->id_irq[0] >= 0)) {
+ if (isdefault && id && id->id_irq[0] >= 0) {
start = id->id_irq[0];
end = id->id_irq[0];
count = 1;
@@ -576,7 +603,6 @@ isa_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
int rv;
- struct resource **rp;
struct isa_device *id = DEVTOISA(child);
if (rid > 1)
@@ -595,7 +621,7 @@ isa_release_resource(device_t bus, device_t child, int type, int rid,
rv = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, type, rid, r);
- if (rv) {
+ if (rv == 0) {
switch (type) {
case SYS_RES_IRQ:
id->id_irqres[rid] = 0;
@@ -652,7 +678,7 @@ isa_handle_intr(void *arg)
outb(IO_ICU1, 0x20 | (irq > 7 ? 2 : irq));
}
-static int
+int
isa_setup_intr(device_t dev, device_t child,
struct resource *irq,
driver_intr_t *intr, void *arg, void **cookiep)
@@ -681,10 +707,15 @@ isa_setup_intr(device_t dev, device_t child,
isa_intr_enable(irq->r_start);
*cookiep = ii;
+
+ if (child)
+ device_printf(child, "interrupting at ISA irq %d\n",
+ (int)irq->r_start);
+
return 0;
}
-static int
+int
isa_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie)
{
@@ -696,6 +727,4 @@ isa_teardown_intr(device_t dev, device_t child,
return 0;
}
-DRIVER_MODULE(isa, cia, isa_driver, isa_devclass, 0, 0);
-DRIVER_MODULE(isa, apecs, isa_driver, isa_devclass, 0, 0);
-DRIVER_MODULE(isa, lca, isa_driver, isa_devclass, 0, 0);
+DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0);
diff --git a/sys/alpha/isa/isavar.h b/sys/alpha/isa/isavar.h
new file mode 100644
index 0000000..ce0e8ce
--- /dev/null
+++ b/sys/alpha/isa/isavar.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * Export low-level interrupt handling code for chipsets which route
+ * interrupts via the ISA interrupt controller.
+ */
+void isa_init_intr(void);
+struct resource *isa_alloc_intr(device_t bus, device_t child, int irq);
+int isa_release_intr(device_t bus, device_t child, struct resource *r);
+int isa_setup_intr(device_t dev, device_t child, struct resource *irq,
+ driver_intr_t *intr, void *arg, void **cookiep);
+int isa_teardown_intr(device_t dev, device_t child, struct resource *irq,
+ void *cookie);
diff --git a/sys/alpha/pci/apecs.c b/sys/alpha/pci/apecs.c
index 66bedcf..fb86dc9 100644
--- a/sys/alpha/pci/apecs.c
+++ b/sys/alpha/pci/apecs.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: apecs.c,v 1.4 1998/12/04 22:54:42 archie Exp $
+ * $Id: apecs.c,v 1.5 1999/01/18 20:15:07 gallatin Exp $
*/
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@@ -60,12 +60,15 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
+#include <machine/bus.h>
#include <sys/rman.h>
#include <alpha/pci/apecsreg.h>
#include <alpha/pci/apecsvar.h>
#include <alpha/pci/pcibus.h>
+#include <alpha/isa/isavar.h>
#include <machine/intr.h>
+#include <machine/resource.h>
#include <machine/intrcnt.h>
#include <machine/cpuconf.h>
#include <machine/swiz.h>
@@ -75,7 +78,6 @@
static devclass_t apecs_devclass;
static device_t apecs0; /* XXX only one for now */
-static device_t isa0;
struct apecs_softc {
vm_offset_t dmem_base; /* dense memory */
@@ -442,18 +444,25 @@ apecs_write_hae(u_int64_t hae)
static int apecs_probe(device_t dev);
static int apecs_attach(device_t dev);
+static struct resource *apecs_alloc_resource(device_t bus, device_t child,
+ int type, int *rid, u_long start,
+ u_long end, u_long count,
+ u_int flags);
+static int apecs_release_resource(device_t bus, device_t child,
+ int type, int rid, struct resource *r);
static int apecs_setup_intr(device_t dev, device_t child, struct resource *irq,
driver_intr_t *intr, void *arg, void **cookiep);
static int apecs_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie);
+
static device_method_t apecs_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, apecs_probe),
DEVMETHOD(device_attach, apecs_attach),
/* Bus interface */
- DEVMETHOD(bus_alloc_resource, pci_alloc_resource),
- DEVMETHOD(bus_release_resource, pci_release_resource),
+ DEVMETHOD(bus_alloc_resource, apecs_alloc_resource),
+ DEVMETHOD(bus_release_resource, apecs_release_resource),
DEVMETHOD(bus_activate_resource, pci_activate_resource),
DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
DEVMETHOD(bus_setup_intr, apecs_setup_intr),
@@ -499,29 +508,19 @@ apecs_probe(device_t dev)
apecs_hae_mem = REGVAL(EPIC_HAXR1);
pci_init_resources();
+ isa_init_intr();
- isa0 = device_add_child(dev, "isa", 0, 0);
+ device_add_child(dev, "pcib", 0, 0);
return 0;
}
-extern void isa_intr(void* frame, u_long vector);
-
static int
apecs_attach(device_t dev)
{
struct apecs_softc* sc = APECS_SOFTC(dev);
apecs_init();
- /*
- * the avanti routes interrupts through the isa interrupt
- * controller, so we need to special case it
- */
- if(hwrpb->rpb_type == ST_DEC_2100_A50)
- chipset.intrdev = isa0;
- else
- chipset.intrdev = apecs0;
-
sc->dmem_base = APECS_PCI_DENSE;
sc->smem_base = APECS_PCI_SPARSE;
sc->io_base = APECS_PCI_SIO;
@@ -541,6 +540,27 @@ apecs_attach(device_t dev)
return 0;
}
+static struct resource *
+apecs_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ if (type == SYS_RES_IRQ)
+ return isa_alloc_intr(bus, child, start);
+ else
+ return pci_alloc_resource(bus, child, type, rid,
+ start, end, count, flags);
+}
+
+static int
+apecs_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ if (type == SYS_RES_IRQ)
+ return isa_release_intr(bus, child, r);
+ else
+ return pci_release_resource(bus, child, type, rid, r);
+}
+
static int
apecs_setup_intr(device_t dev, device_t child,
struct resource *irq,
@@ -548,6 +568,13 @@ apecs_setup_intr(device_t dev, device_t child,
{
int error;
+ /*
+ * the avanti routes interrupts through the isa interrupt
+ * controller, so we need to special case it
+ */
+ if(hwrpb->rpb_type == ST_DEC_2100_A50)
+ return isa_setup_intr(dev, child, irq, intr, arg, cookiep);
+
error = rman_activate_resource(irq);
if (error)
return error;
@@ -567,6 +594,13 @@ static int
apecs_teardown_intr(device_t dev, device_t child,
struct resource *irq, void *cookie)
{
+ /*
+ * the avanti routes interrupts through the isa interrupt
+ * controller, so we need to special case it
+ */
+ if(hwrpb->rpb_type == ST_DEC_2100_A50)
+ return isa_teardown_intr(dev, child, irq, cookie);
+
alpha_teardown_intr(cookie);
return rman_deactivate_resource(irq);
}
diff --git a/sys/alpha/pci/apecs_pci.c b/sys/alpha/pci/apecs_pci.c
new file mode 100644
index 0000000..fb0b339
--- /dev/null
+++ b/sys/alpha/pci/apecs_pci.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPEAPECSL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+static devclass_t pcib_devclass;
+
+static int
+apecs_pcib_probe(device_t dev)
+{
+ device_set_desc(dev, "2107x PCI host bus adapter");
+
+ device_add_child(dev, "pci", 0, 0);
+
+ return 0;
+}
+
+static device_method_t apecs_pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, apecs_pcib_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t apecs_pcib_driver = {
+ "pcib",
+ apecs_pcib_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+DRIVER_MODULE(pcib, apecs, apecs_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/alpha/pci/cia.c b/sys/alpha/pci/cia.c
index 350df00..e967493 100644
--- a/sys/alpha/pci/cia.c
+++ b/sys/alpha/pci/cia.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cia.c,v 1.14 1998/12/04 22:54:42 archie Exp $
+ * $Id: cia.c,v 1.15 1999/03/28 17:52:17 dfr Exp $
*/
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -96,6 +96,7 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
+#include <machine/bus.h>
#include <sys/rman.h>
#include <alpha/pci/ciareg.h>
@@ -654,6 +655,7 @@ static device_method_t cia_methods[] = {
DEVMETHOD(device_attach, cia_attach),
/* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_alloc_resource, pci_alloc_resource),
DEVMETHOD(bus_release_resource, pci_release_resource),
DEVMETHOD(bus_activate_resource, pci_activate_resource),
@@ -724,11 +726,12 @@ cia_probe(device_t dev)
if (cia0)
return ENXIO;
cia0 = dev;
- device_set_desc(dev, "2117x PCI adapter"); /* XXX */
+ device_set_desc(dev, "2117x Core Logic chipset"); /* XXX */
pci_init_resources();
+ isa_init_intr();
- device_add_child(dev, "isa", 0, 0);
+ device_add_child(dev, "pcib", 0, 0);
return 0;
}
@@ -736,12 +739,10 @@ cia_probe(device_t dev)
static int
cia_attach(device_t dev)
{
- struct cia_softc* sc = CIA_SOFTC(dev);
char* name;
int pass;
cia_init();
- chipset.intrdev = dev;
name = cia_ispyxis ? "Pyxis" : "ALCOR/ALCOR2";
if (cia_ispyxis) {
@@ -832,6 +833,9 @@ cia_setup_intr(device_t dev, device_t child,
/* Enable PCI interrupt */
platform.pci_intr_enable(irq->r_start);
+ device_printf(child, "interrupting at CIA irq %d\n",
+ (int) irq->r_start);
+
return 0;
}
@@ -844,4 +848,3 @@ cia_teardown_intr(device_t dev, device_t child,
}
DRIVER_MODULE(cia, root, cia_driver, cia_devclass, 0, 0);
-
diff --git a/sys/alpha/pci/cia_pci.c b/sys/alpha/pci/cia_pci.c
new file mode 100644
index 0000000..e77c3b4
--- /dev/null
+++ b/sys/alpha/pci/cia_pci.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+static devclass_t pcib_devclass;
+
+static int
+cia_pcib_probe(device_t dev)
+{
+ device_set_desc(dev, "2117x PCI host bus adapter");
+
+ device_add_child(dev, "pci", 0, 0);
+
+ return 0;
+}
+
+static device_method_t cia_pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, cia_pcib_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t cia_pcib_driver = {
+ "pcib",
+ cia_pcib_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+DRIVER_MODULE(pcib, cia, cia_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/alpha/pci/lca.c b/sys/alpha/pci/lca.c
index f3b194d..b60fb3e 100644
--- a/sys/alpha/pci/lca.c
+++ b/sys/alpha/pci/lca.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: lca.c,v 1.4 1998/11/15 18:25:16 dfr Exp $
+ * $Id: lca.c,v 1.5 1998/12/04 22:54:42 archie Exp $
*/
#include <sys/param.h>
@@ -35,15 +35,16 @@
#include <alpha/pci/lcareg.h>
#include <alpha/pci/lcavar.h>
#include <alpha/pci/pcibus.h>
-#include <machine/swiz.h>
+#include <alpha/isa/isavar.h>
#include <machine/intr.h>
+#include <machine/resource.h>
#include <machine/cpuconf.h>
+#include <machine/swiz.h>
#define KV(pa) ALPHA_PHYS_TO_K0SEG(pa)
static devclass_t lca_devclass;
static device_t lca0; /* XXX only one for now */
-static device_t isa0;
struct lca_softc {
int junk;
@@ -333,8 +334,12 @@ lca_write_hae(u_int64_t hae)
static int lca_probe(device_t dev);
static int lca_attach(device_t dev);
-static void *lca_create_intr(device_t dev, device_t child, int irq, driver_intr_t *intr, void *arg);
-static int lca_connect_intr(device_t dev, void* ih);
+static struct resource *lca_alloc_resource(device_t bus, device_t child,
+ int type, int *rid, u_long start,
+ u_long end, u_long count,
+ u_int flags);
+static int lca_release_resource(device_t bus, device_t child,
+ int type, int rid, struct resource *r);
static device_method_t lca_methods[] = {
/* Device interface */
@@ -342,10 +347,12 @@ static device_method_t lca_methods[] = {
DEVMETHOD(device_attach, lca_attach),
/* Bus interface */
- DEVMETHOD(bus_alloc_resource, pci_alloc_resource),
- DEVMETHOD(bus_release_resource, pci_release_resource),
+ DEVMETHOD(bus_alloc_resource, lca_alloc_resource),
+ DEVMETHOD(bus_release_resource, lca_release_resource),
DEVMETHOD(bus_activate_resource, pci_activate_resource),
DEVMETHOD(bus_deactivate_resource, pci_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, isa_setup_intr),
+ DEVMETHOD(bus_teardown_intr, isa_teardown_intr),
{ 0, 0 }
};
@@ -380,9 +387,12 @@ lca_probe(device_t dev)
if (lca0)
return ENXIO;
lca0 = dev;
- device_set_desc(dev, "21066 PCI adapter"); /* XXX */
+ device_set_desc(dev, "21066 Core Logic chipset"); /* XXX */
+
+ pci_init_resources();
+ isa_init_intr();
- isa0 = device_add_child(dev, "isa", 0, 0);
+ device_add_child(dev, "pcib", 0, 0);
return 0;
}
@@ -393,7 +403,6 @@ lca_attach(device_t dev)
struct lca_softc* sc = LCA_SOFTC(dev);
lca_init();
- chipset.intrdev = isa0;
set_iointr(alpha_dispatch_intr);
@@ -408,5 +417,26 @@ lca_attach(device_t dev)
return 0;
}
+static struct resource *
+lca_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ if (type == SYS_RES_IRQ)
+ return isa_alloc_intr(bus, child, start);
+ else
+ return pci_alloc_resource(bus, child, type, rid,
+ start, end, count, flags);
+}
+
+static int
+lca_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ if (type == SYS_RES_IRQ)
+ return isa_release_intr(bus, child, r);
+ else
+ return pci_release_resource(bus, child, type, rid, r);
+}
+
DRIVER_MODULE(lca, root, lca_driver, lca_devclass, 0, 0);
diff --git a/sys/alpha/pci/lca_pci.c b/sys/alpha/pci/lca_pci.c
new file mode 100644
index 0000000..61e3525
--- /dev/null
+++ b/sys/alpha/pci/lca_pci.c
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPELCAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+static devclass_t pcib_devclass;
+
+static int
+lca_pcib_probe(device_t dev)
+{
+ device_set_desc(dev, "21066 PCI host bus adapter");
+
+ device_add_child(dev, "pci", 0, 0);
+
+ return 0;
+}
+
+static device_method_t lca_pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, lca_pcib_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t lca_pcib_driver = {
+ "pcib",
+ lca_pcib_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+DRIVER_MODULE(pcib, lca, lca_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/alpha/pci/pcibus.c b/sys/alpha/pci/pcibus.c
index 697373c..ffb726a 100644
--- a/sys/alpha/pci/pcibus.c
+++ b/sys/alpha/pci/pcibus.c
@@ -23,7 +23,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: pcibus.c,v 1.7 1998/11/18 23:53:12 dfr Exp $
+ * $Id: pcibus.c,v 1.8 1998/12/27 18:03:29 dfr Exp $
*
*/
@@ -32,6 +32,7 @@
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/bus.h>
+#include <machine/bus.h>
#include <sys/interrupt.h>
#include <sys/sysctl.h>
#include <sys/rman.h>
@@ -40,6 +41,7 @@
#include <machine/chipset.h>
#include <machine/cpuconf.h>
#include <machine/resource.h>
+#include <alpha/pci/pcibus.h>
char chipset_type[10];
int chipset_bwx = 0;
@@ -129,6 +131,8 @@ pci_cvt_to_bwx(vm_offset_t sparse)
return NULL;
}
+#if 0
+
/*
* These can disappear when I update the pci code to use the new
* device framework.
@@ -160,6 +164,8 @@ intr_connect(struct intrec *idesc)
return 0;
}
+#endif
+
void
alpha_platform_assign_pciintr(pcicfgregs *cfg)
{
@@ -167,6 +173,20 @@ alpha_platform_assign_pciintr(pcicfgregs *cfg)
platform.pci_intr_map((void *)cfg);
}
+int
+alpha_platform_setup_ide_intr(int chan, driver_intr_t *fn, void *arg)
+{
+ if (platform.pci_setup_ide_intr)
+ return platform.pci_setup_ide_intr(chan, fn, arg);
+ else {
+ int irqs[2] = { 14, 15 };
+ void *junk;
+ struct resource *res;
+ res = isa_alloc_intr(0, 0, irqs[chan]);
+ return isa_setup_intr(0, 0, res, fn, arg, &junk);
+ }
+}
+
static struct rman irq_rman, port_rman, mem_rman;
void pci_init_resources()
@@ -177,23 +197,23 @@ void pci_init_resources()
irq_rman.rm_descr = "PCI Interrupt request lines";
if (rman_init(&irq_rman)
|| rman_manage_region(&irq_rman, 0, 31))
- panic("cia_probe irq_rman");
+ panic("pci_init_resources irq_rman");
port_rman.rm_start = 0;
- port_rman.rm_end = 0xffff;
+ port_rman.rm_end = ~0u;
port_rman.rm_type = RMAN_ARRAY;
port_rman.rm_descr = "I/O ports";
if (rman_init(&port_rman)
- || rman_manage_region(&port_rman, 0, 0xffff))
- panic("cia_probe port_rman");
+ || rman_manage_region(&port_rman, 0x0, (1L << 32)))
+ panic("pci_init_resources port_rman");
mem_rman.rm_start = 0;
mem_rman.rm_end = ~0u;
mem_rman.rm_type = RMAN_ARRAY;
- mem_rman.rm_descr = "I/O memory addresses";
+ mem_rman.rm_descr = "I/O memory";
if (rman_init(&mem_rman)
|| rman_manage_region(&mem_rman, 0x0, (1L << 32)))
- panic("cia_probe mem_rman");
+ panic("pci_init_resources mem_rman");
}
/*
@@ -205,6 +225,7 @@ pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct rman *rm;
+ struct resource *rv;
switch (type) {
case SYS_RES_IRQ:
@@ -223,7 +244,20 @@ pci_alloc_resource(device_t bus, device_t child, int type, int *rid,
return 0;
}
- return rman_reserve_resource(rm, start, end, count, flags, child);
+ rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (rv == 0)
+ return 0;
+
+ if (type == SYS_RES_MEMORY) {
+ rman_set_bustag(rv, ALPHA_BUS_SPACE_MEM);
+ rman_set_bushandle(rv, rv->r_start);
+ rman_set_virtual(rv, (void *) rv->r_start); /* XXX */
+ } else if (type == SYS_RES_IOPORT) {
+ rman_set_bustag(rv, ALPHA_BUS_SPACE_IO);
+ rman_set_bushandle(rv, rv->r_start);
+ }
+
+ return rv;
}
int
@@ -266,12 +300,37 @@ memcpy_toio(u_int32_t d, void *s, size_t size)
}
void
+memcpy_io(u_int32_t d, u_int32_t s, size_t size)
+{
+ while (size--)
+ writeb(d++, readb(s++));
+}
+
+void
memset_io(u_int32_t d, int val, size_t size)
{
while (size--)
writeb(d++, val);
}
+void
+memsetw(void *d, int val, size_t size)
+{
+ u_int16_t *sp = d;
+
+ while (size--)
+ *sp++ = val;
+}
+
+void
+memsetw_io(u_int32_t d, int val, size_t size)
+{
+ while (size--) {
+ writew(d, val);
+ d += sizeof(u_int16_t);
+ }
+}
+
#include "opt_ddb.h"
#ifdef DDB
#include <ddb/ddb.h>
@@ -280,7 +339,6 @@ DB_COMMAND(in, db_in)
{
int c;
int size;
- u_int32_t val;
if (!have_addr)
return;
@@ -307,7 +365,7 @@ DB_COMMAND(in, db_in)
if (count <= 0) count = 1;
while (--count >= 0) {
- db_printf("%08x:\t", addr);
+ db_printf("%08lx:\t", addr);
switch (size) {
case 1:
db_printf("%02x\n", inb(addr));
diff --git a/sys/alpha/tc/tc.c b/sys/alpha/tc/tc.c
index 0c88726..dd99f14 100644
--- a/sys/alpha/tc/tc.c
+++ b/sys/alpha/tc/tc.c
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: tc.c,v 1.1 1998/08/20 08:27:10 dfr Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
* All rights reserved.
@@ -568,8 +568,6 @@ tc_attach(device_t dev)
tc0 = dev;
- chipset.intrdev = dev;
-
switch(hwrpb->rpb_type){
#ifdef DEC_3000_300
case ST_DEC_3000_300:
diff --git a/sys/alpha/tc/tcasic.c b/sys/alpha/tc/tcasic.c
index 1dd4fee..eeb6953 100644
--- a/sys/alpha/tc/tcasic.c
+++ b/sys/alpha/tc/tcasic.c
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: tcasic.c,v 1.1 1998/08/20 08:27:11 dfr Exp $ */
/* from $NetBSD: tcasic.c,v 1.23 1998/05/14 00:01:31 thorpej Exp $ */
/*
@@ -97,7 +97,6 @@ tcasic_attach(device_t dev)
tcasic0 = dev;
/* chipset = tcasic_chipset;*/
- chipset.intrdev = dev;
device_probe_and_attach(tc0);
return 0;
}
diff --git a/sys/alpha/tlsb/dwlpx.c b/sys/alpha/tlsb/dwlpx.c
index bb80abf..5a2a5cd 100644
--- a/sys/alpha/tlsb/dwlpx.c
+++ b/sys/alpha/tlsb/dwlpx.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: dwlpx.c,v 1.6 1998/09/04 08:01:26 dfr Exp $
+ * $Id: dwlpx.c,v 1.7 1998/11/15 18:25:16 dfr Exp $
*/
#include "opt_simos.h"
@@ -293,7 +293,7 @@ dwlpx_attach(device_t dev)
dwlpx0 = dev;
chipset = dwlpx_chipset;
- chipset.intrdev = dev;
+ /* chipset.intrdev = dev; */
regs = KV(DWLPX_BASE(kft_get_node(dev), kft_get_hosenum(dev)));
sc->dmem_base = regs + (0L << 32);
diff --git a/sys/amd64/amd64/autoconf.c b/sys/amd64/amd64/autoconf.c
index fc7ab85..c501281 100644
--- a/sys/amd64/amd64/autoconf.c
+++ b/sys/amd64/amd64/autoconf.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
- * $Id: autoconf.c,v 1.111 1999/01/19 00:10:59 peter Exp $
+ * $Id: autoconf.c,v 1.112 1999/04/15 14:52:24 bde Exp $
*/
/*
@@ -50,9 +50,11 @@
#include "opt_cd9660.h"
#include "opt_mfs.h"
#include "opt_nfsroot.h"
+#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/disklabel.h>
#include <sys/diskslice.h>
@@ -74,13 +76,19 @@
#include "isa.h"
#if NISA > 0
+#ifdef OLD_BUS_ARCH
#include <i386/isa/isa_device.h>
+#else
+device_t isa_bus_device = 0;
+#endif /* OLD_BUS_ARCH */
#endif
#include "pnp.h"
#if NPNP > 0
+#ifdef OLD_BUS_ARCH
#include <i386/isa/pnp.h>
#endif
+#endif
#include "eisa.h"
#if NEISA > 0
@@ -92,8 +100,6 @@
#include <pci/pcivar.h>
#endif
-#include <sys/bus.h>
-
static void configure_first __P((void *));
static void configure __P((void *));
static void configure_final __P((void *));
@@ -186,6 +192,8 @@ configure_finish()
{
}
+device_t nexus_dev;
+
/*
* Determine i/o configuration for a machine.
*/
@@ -228,21 +236,21 @@ configure(dummy)
eisa_configure();
#endif
-#if NPCI > 0
- pci_configure();
-#endif
-
#if NPNP > 0
pnp_configure();
#endif
-#if NISA > 0
- isa_configure();
-#endif
+ /* nexus0 is the top of the i386 device tree */
+ device_add_child(root_bus, "nexus", 0, 0);
/* initialize new bus architecture */
root_bus_configure();
+#if NISA > 0
+ if (isa_bus_device)
+ bus_generic_attach(isa_bus_device);
+#endif
+
/*
* Now we're ready to handle (pending) interrupts.
* XXX this is slightly misplaced.
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index 79e1d1a..a9286fa 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: exception.s,v 1.56 1999/02/25 11:03:08 bde Exp $
+ * $Id: exception.s,v 1.57 1999/02/28 10:53:28 bde Exp $
*/
#include "npx.h"
@@ -139,7 +139,7 @@ IDTVEC(fpu)
#if NNPX > 0
/*
* Handle like an interrupt (except for accounting) so that we can
- * call npxintr to clear the error. It would be better to handle
+ * call npx_intr to clear the error. It would be better to handle
* npx interrupts as traps. This used to be difficult for nested
* interrupts, but now it is fairly easy - mask nested ones the
* same as SWI_AST's.
@@ -180,7 +180,7 @@ IDTVEC(fpu)
movl %eax,_cpl
#endif /* SMP */
- call _npxintr
+ call _npx_intr
incb _intr_nesting_level
MEXITCOUNT
diff --git a/sys/amd64/amd64/exception.s b/sys/amd64/amd64/exception.s
index 79e1d1a..a9286fa 100644
--- a/sys/amd64/amd64/exception.s
+++ b/sys/amd64/amd64/exception.s
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: exception.s,v 1.56 1999/02/25 11:03:08 bde Exp $
+ * $Id: exception.s,v 1.57 1999/02/28 10:53:28 bde Exp $
*/
#include "npx.h"
@@ -139,7 +139,7 @@ IDTVEC(fpu)
#if NNPX > 0
/*
* Handle like an interrupt (except for accounting) so that we can
- * call npxintr to clear the error. It would be better to handle
+ * call npx_intr to clear the error. It would be better to handle
* npx interrupts as traps. This used to be difficult for nested
* interrupts, but now it is fairly easy - mask nested ones the
* same as SWI_AST's.
@@ -180,7 +180,7 @@ IDTVEC(fpu)
movl %eax,_cpl
#endif /* SMP */
- call _npxintr
+ call _npx_intr
incb _intr_nesting_level
MEXITCOUNT
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c
index 2371e7b..dc2eb73 100644
--- a/sys/amd64/amd64/fpu.c
+++ b/sys/amd64/amd64/fpu.c
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
- * $Id: npx.c,v 1.65 1999/01/08 16:29:59 bde Exp $
+ * $Id: npx.c,v 1.66 1999/03/28 23:28:18 dt Exp $
*/
#include "npx.h"
@@ -43,10 +43,14 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
#ifdef NPX_DEBUG
#include <sys/syslog.h>
#endif
@@ -64,6 +68,7 @@
#ifndef SMP
#include <machine/clock.h>
#endif
+#include <machine/resource.h>
#include <machine/specialreg.h>
#include <machine/segments.h>
@@ -72,7 +77,6 @@
#include <i386/isa/intr_machdep.h>
#include <i386/isa/isa.h>
#endif
-#include <i386/isa/isa_device.h>
/*
* 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
@@ -83,9 +87,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)))
@@ -119,18 +120,15 @@ 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));
+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,
@@ -191,12 +189,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 */
@@ -213,20 +212,20 @@ 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;
+ npx_intrno = NRSVIDT + 13;
save_eflags = read_eflags();
disable_intr();
save_icu1_mask = inb(IO_ICU1 + 1);
save_icu2_mask = inb(IO_ICU2 + 1);
save_idt_npxintr = idt[npx_intrno];
save_idt_npxtrap = idt[16];
- 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)));
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();
outb(IO_ICU1 + 1, save_icu1_mask);
outb(IO_ICU2 + 1, save_icu2_mask);
@@ -239,8 +238,8 @@ npxprobe(dvp)
}
static int
-npxprobe1(dvp)
- struct isa_device *dvp;
+npx_probe1(dev)
+ device_t dev;
{
#ifndef SMP
u_short control;
@@ -280,21 +279,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.
@@ -335,14 +331,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.
*/
@@ -350,8 +344,30 @@ npxprobe1(dvp)
/*
* npxattach would be too late to set npx0_imask.
*/
- npx0_imask |= dvp->id_irq;
- return (IO_NPXSIZE);
+ npx0_imask |= (1 << 13);
+
+ /*
+ * 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;
+ r = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &rid, 13, 13,
+ 1, RF_ACTIVE);
+ 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.
@@ -363,13 +379,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 */
}
@@ -377,14 +387,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)
@@ -401,23 +412,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 */
}
/*
@@ -494,8 +508,8 @@ npxexit(p)
* solution for signals other than SIGFPE.
*/
void
-npxintr(unit)
- int unit;
+npx_intr(dummy)
+ void *dummy;
{
int code;
struct intrframe *frame;
@@ -518,7 +532,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
@@ -686,4 +700,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/amd64/amd64/legacy.c b/sys/amd64/amd64/legacy.c
new file mode 100644
index 0000000..7df4387
--- /dev/null
+++ b/sys/amd64/amd64/legacy.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright 1998 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * This code implements a `root nexus' for Intel Architecture
+ * machines. The function of the root nexus is to serve as an
+ * attachment point for both processors and buses, and to manage
+ * resources which are common to all of them. In particular,
+ * this code implements the core resource managers for interrupt
+ * requests, DMA requests (which rightfully should be a part of the
+ * ISA code but it's easier to do it here for now), I/O port addresses,
+ * and I/O memory address space.
+ */
+
+#include "opt_smp.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/vmparam.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/pmap.h>
+
+#include <machine/ipl.h>
+#include <machine/resource.h>
+#ifdef APIC_IO
+#include <machine/smp.h>
+#include <machine/mpapic.h>
+#endif
+
+#include <i386/isa/isa.h>
+#include <i386/isa/icu.h>
+#include <i386/isa/intr_machdep.h>
+
+#include <pci/pcivar.h>
+
+#include "eisa.h"
+#include "isa.h"
+#include "pci.h"
+#include "npx.h"
+#include "apm.h"
+
+static struct rman irq_rman, drq_rman, port_rman, mem_rman;
+
+static int nexus_probe(device_t);
+static void nexus_print_child(device_t, device_t);
+static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+static int nexus_activate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_deactivate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_release_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_setup_intr(device_t, device_t, struct resource *,
+ void (*)(void *), void *, void **);
+static int nexus_teardown_intr(device_t, device_t, struct resource *,
+ void *);
+
+static device_method_t nexus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, nexus_print_child),
+ DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
+ DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
+ DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
+ DEVMETHOD(bus_release_resource, nexus_release_resource),
+ DEVMETHOD(bus_activate_resource, nexus_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, nexus_setup_intr),
+ DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t nexus_driver = {
+ "nexus",
+ nexus_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+static devclass_t nexus_devclass;
+
+DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
+
+#ifdef APIC_IO
+#define LASTIRQ (NINTR - 1)
+#else
+#define LASTIRQ 15
+#endif
+
+static int
+nexus_probe(device_t dev)
+{
+ device_t child;
+
+ device_quiet(dev); /* suppress attach message for neatness */
+
+ irq_rman.rm_start = 0;
+ irq_rman.rm_end = LASTIRQ;
+ irq_rman.rm_type = RMAN_ARRAY;
+ irq_rman.rm_descr = "Interrupt request lines";
+ if (rman_init(&irq_rman)
+ || rman_manage_region(&irq_rman, 0, 1)
+ || rman_manage_region(&irq_rman, 3, LASTIRQ))
+ panic("nexus_probe irq_rman");
+
+ drq_rman.rm_start = 0;
+ drq_rman.rm_end = 7;
+ drq_rman.rm_type = RMAN_ARRAY;
+ drq_rman.rm_descr = "DMA request lines";
+ /* XXX drq 0 not available on some machines */
+ if (rman_init(&drq_rman)
+ || rman_manage_region(&drq_rman, 0, 7))
+ panic("nexus_probe drq_rman");
+
+ port_rman.rm_start = 0;
+ port_rman.rm_end = 0xffff;
+ port_rman.rm_type = RMAN_ARRAY;
+ port_rman.rm_descr = "I/O ports";
+ if (rman_init(&port_rman)
+ || rman_manage_region(&port_rman, 0, 0xffff))
+ panic("nexus_probe port_rman");
+
+ mem_rman.rm_start = 0;
+ mem_rman.rm_end = ~0u;
+ mem_rman.rm_type = RMAN_ARRAY;
+ mem_rman.rm_descr = "I/O memory addresses";
+ if (rman_init(&mem_rman)
+ || rman_manage_region(&mem_rman, 0, ~0))
+ panic("nexus_probe mem_rman");
+
+#if NNPX > 0
+ child = device_add_child(dev, "npx", 0, 0);
+ if (child == 0)
+ panic("nexus_probe npx");
+#endif /* NNPX > 0 */
+#if NAPM > 0
+ child = device_add_child(dev, "apm", 0, 0);
+ if (child == 0)
+ panic("nexus_probe apm");
+#endif /* NAPM > 0 */
+#if NPCI > 0
+ /* Add a PCI bridge if pci bus is present */
+ if (pci_cfgopen() != 0) {
+ child = device_add_child(dev, "pcib", 0, 0);
+ if (child == 0)
+ panic("nexus_probe pcib");
+ }
+#endif
+#if 0 && NEISA > 0
+ child = device_add_child(dev, "eisa", 0, 0);
+ if (child == 0)
+ panic("nexus_probe eisa");
+#endif
+#if NISA > 0
+ /* Add an ISA bus directly if pci bus is not present */
+ if (pci_cfgopen() == 0) {
+ child = device_add_child(dev, "isa", 0, 0);
+ if (child == 0)
+ panic("nexus_probe isa");
+ }
+#endif
+ return 0;
+}
+
+static void
+nexus_print_child(device_t bus, device_t child)
+{
+ printf(" on motherboard");
+}
+
+/*
+ * Allocate a resource on behalf of child. NB: child is usually going to be a
+ * child of one of our descendants, not a direct child of nexus0.
+ * (Exceptions include npx.)
+ */
+static struct resource *
+nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct resource *rv;
+ struct rman *rm;
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ rm = &irq_rman;
+ break;
+
+ case SYS_RES_DRQ:
+ rm = &drq_rman;
+ break;
+
+ case SYS_RES_IOPORT:
+ rm = &port_rman;
+ break;
+
+ case SYS_RES_MEMORY:
+ rm = &mem_rman;
+ break;
+
+ default:
+ return 0;
+ }
+
+ rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (rv == 0)
+ return 0;
+
+ if (type == SYS_RES_MEMORY) {
+ caddr_t vaddr = 0;
+
+ if (rv->r_end < 1024 * 1024 * 1024) {
+ /*
+ * The first 1Mb is mapped at KERNBASE.
+ */
+ vaddr = (caddr_t)((uintptr_t)KERNBASE + rv->r_start);
+ } else {
+ u_int32_t paddr;
+ u_int32_t psize;
+ u_int32_t poffs;
+
+ paddr = rv->r_start;
+ psize = rv->r_end - rv->r_start;
+
+ poffs = paddr - trunc_page(paddr);
+ vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
+ }
+ rman_set_virtual(rv, vaddr);
+ rman_set_bustag(rv, I386_BUS_SPACE_MEM);
+ rman_set_bushandle(rv, (bus_space_handle_t) vaddr);
+ } else if (type == SYS_RES_IOPORT) {
+ rman_set_bustag(rv, I386_BUS_SPACE_IO);
+ rman_set_bushandle(rv, rv->r_start);
+ }
+ return rv;
+}
+
+static int
+nexus_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_activate_resource(r));
+}
+
+static int
+nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_deactivate_resource(r));
+}
+
+static int
+nexus_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_release_resource(r));
+}
+
+/*
+ * Currently this uses the really grody interface from kern/kern_intr.c
+ * (which really doesn't belong in kern/anything.c). Eventually, all of
+ * the code in kern_intr.c and machdep_intr.c should get moved here, since
+ * this is going to be the official interface.
+ */
+static int
+nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
+ void (*ihand)(void *), void *arg, void **cookiep)
+{
+ intrmask_t *mask;
+ driver_t *driver;
+ int error, icflags;
+
+ if (child)
+ device_printf(child, "interrupting at irq %d\n",
+ (int)irq->r_start);
+
+ *cookiep = 0;
+ if (irq->r_flags & RF_SHAREABLE)
+ icflags = 0;
+ else
+ icflags = INTR_EXCL;
+
+ driver = device_get_driver(child);
+ switch (driver->type) {
+ case DRIVER_TYPE_TTY:
+ mask = &tty_imask;
+ break;
+ case (DRIVER_TYPE_TTY | DRIVER_TYPE_FAST):
+ mask = &tty_imask;
+ icflags |= INTR_FAST;
+ break;
+ case DRIVER_TYPE_BIO:
+ mask = &bio_imask;
+ break;
+ case DRIVER_TYPE_NET:
+ mask = &net_imask;
+ break;
+ case DRIVER_TYPE_CAM:
+ mask = &cam_imask;
+ break;
+ case DRIVER_TYPE_MISC:
+ mask = 0;
+ break;
+ default:
+ panic("still using grody create_intr interface");
+ }
+
+ /*
+ * We depend here on rman_activate_resource() being idempotent.
+ */
+ error = rman_activate_resource(irq);
+ if (error)
+ return (error);
+
+ *cookiep = intr_create((void *)(intptr_t)-1, irq->r_start, ihand, arg,
+ mask, icflags);
+ if (*cookiep)
+ error = intr_connect(*cookiep);
+ else
+ error = EINVAL; /* XXX ??? */
+
+ return (error);
+}
+
+static int
+nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
+{
+ return (intr_destroy(ih));
+}
+
+static devclass_t pcib_devclass;
+
+static int
+nexus_pcib_probe(device_t dev)
+{
+ device_set_desc(dev, "PCI host bus adapter");
+
+ device_add_child(dev, "pci", 0, 0);
+
+ return 0;
+}
+
+static device_method_t nexus_pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_pcib_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t nexus_pcib_driver = {
+ "pcib",
+ nexus_pcib_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+DRIVER_MODULE(pcib, nexus, nexus_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 6ed3182..6980279 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.327 1999/03/06 04:46:18 wollman Exp $
+ * $Id: machdep.c,v 1.328 1999/04/03 22:19:58 jdp Exp $
*/
#include "apm.h"
@@ -71,6 +71,7 @@
#include <sys/sysent.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
+#include <sys/bus.h>
#ifdef SYSVSHM
#include <sys/shm.h>
@@ -125,7 +126,9 @@
#include <machine/perfmon.h>
#endif
+#ifdef OLD_BUS_ARCH
#include <i386/isa/isa_device.h>
+#endif
#include <i386/isa/intr_machdep.h>
#ifndef VM86
#include <i386/isa/rtc.h>
@@ -1164,8 +1167,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;
@@ -1454,10 +1459,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/amd64/amd64/nexus.c b/sys/amd64/amd64/nexus.c
new file mode 100644
index 0000000..7df4387
--- /dev/null
+++ b/sys/amd64/amd64/nexus.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright 1998 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * This code implements a `root nexus' for Intel Architecture
+ * machines. The function of the root nexus is to serve as an
+ * attachment point for both processors and buses, and to manage
+ * resources which are common to all of them. In particular,
+ * this code implements the core resource managers for interrupt
+ * requests, DMA requests (which rightfully should be a part of the
+ * ISA code but it's easier to do it here for now), I/O port addresses,
+ * and I/O memory address space.
+ */
+
+#include "opt_smp.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/vmparam.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/pmap.h>
+
+#include <machine/ipl.h>
+#include <machine/resource.h>
+#ifdef APIC_IO
+#include <machine/smp.h>
+#include <machine/mpapic.h>
+#endif
+
+#include <i386/isa/isa.h>
+#include <i386/isa/icu.h>
+#include <i386/isa/intr_machdep.h>
+
+#include <pci/pcivar.h>
+
+#include "eisa.h"
+#include "isa.h"
+#include "pci.h"
+#include "npx.h"
+#include "apm.h"
+
+static struct rman irq_rman, drq_rman, port_rman, mem_rman;
+
+static int nexus_probe(device_t);
+static void nexus_print_child(device_t, device_t);
+static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+static int nexus_activate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_deactivate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_release_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_setup_intr(device_t, device_t, struct resource *,
+ void (*)(void *), void *, void **);
+static int nexus_teardown_intr(device_t, device_t, struct resource *,
+ void *);
+
+static device_method_t nexus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, nexus_print_child),
+ DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
+ DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
+ DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
+ DEVMETHOD(bus_release_resource, nexus_release_resource),
+ DEVMETHOD(bus_activate_resource, nexus_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, nexus_setup_intr),
+ DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t nexus_driver = {
+ "nexus",
+ nexus_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+static devclass_t nexus_devclass;
+
+DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
+
+#ifdef APIC_IO
+#define LASTIRQ (NINTR - 1)
+#else
+#define LASTIRQ 15
+#endif
+
+static int
+nexus_probe(device_t dev)
+{
+ device_t child;
+
+ device_quiet(dev); /* suppress attach message for neatness */
+
+ irq_rman.rm_start = 0;
+ irq_rman.rm_end = LASTIRQ;
+ irq_rman.rm_type = RMAN_ARRAY;
+ irq_rman.rm_descr = "Interrupt request lines";
+ if (rman_init(&irq_rman)
+ || rman_manage_region(&irq_rman, 0, 1)
+ || rman_manage_region(&irq_rman, 3, LASTIRQ))
+ panic("nexus_probe irq_rman");
+
+ drq_rman.rm_start = 0;
+ drq_rman.rm_end = 7;
+ drq_rman.rm_type = RMAN_ARRAY;
+ drq_rman.rm_descr = "DMA request lines";
+ /* XXX drq 0 not available on some machines */
+ if (rman_init(&drq_rman)
+ || rman_manage_region(&drq_rman, 0, 7))
+ panic("nexus_probe drq_rman");
+
+ port_rman.rm_start = 0;
+ port_rman.rm_end = 0xffff;
+ port_rman.rm_type = RMAN_ARRAY;
+ port_rman.rm_descr = "I/O ports";
+ if (rman_init(&port_rman)
+ || rman_manage_region(&port_rman, 0, 0xffff))
+ panic("nexus_probe port_rman");
+
+ mem_rman.rm_start = 0;
+ mem_rman.rm_end = ~0u;
+ mem_rman.rm_type = RMAN_ARRAY;
+ mem_rman.rm_descr = "I/O memory addresses";
+ if (rman_init(&mem_rman)
+ || rman_manage_region(&mem_rman, 0, ~0))
+ panic("nexus_probe mem_rman");
+
+#if NNPX > 0
+ child = device_add_child(dev, "npx", 0, 0);
+ if (child == 0)
+ panic("nexus_probe npx");
+#endif /* NNPX > 0 */
+#if NAPM > 0
+ child = device_add_child(dev, "apm", 0, 0);
+ if (child == 0)
+ panic("nexus_probe apm");
+#endif /* NAPM > 0 */
+#if NPCI > 0
+ /* Add a PCI bridge if pci bus is present */
+ if (pci_cfgopen() != 0) {
+ child = device_add_child(dev, "pcib", 0, 0);
+ if (child == 0)
+ panic("nexus_probe pcib");
+ }
+#endif
+#if 0 && NEISA > 0
+ child = device_add_child(dev, "eisa", 0, 0);
+ if (child == 0)
+ panic("nexus_probe eisa");
+#endif
+#if NISA > 0
+ /* Add an ISA bus directly if pci bus is not present */
+ if (pci_cfgopen() == 0) {
+ child = device_add_child(dev, "isa", 0, 0);
+ if (child == 0)
+ panic("nexus_probe isa");
+ }
+#endif
+ return 0;
+}
+
+static void
+nexus_print_child(device_t bus, device_t child)
+{
+ printf(" on motherboard");
+}
+
+/*
+ * Allocate a resource on behalf of child. NB: child is usually going to be a
+ * child of one of our descendants, not a direct child of nexus0.
+ * (Exceptions include npx.)
+ */
+static struct resource *
+nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct resource *rv;
+ struct rman *rm;
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ rm = &irq_rman;
+ break;
+
+ case SYS_RES_DRQ:
+ rm = &drq_rman;
+ break;
+
+ case SYS_RES_IOPORT:
+ rm = &port_rman;
+ break;
+
+ case SYS_RES_MEMORY:
+ rm = &mem_rman;
+ break;
+
+ default:
+ return 0;
+ }
+
+ rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (rv == 0)
+ return 0;
+
+ if (type == SYS_RES_MEMORY) {
+ caddr_t vaddr = 0;
+
+ if (rv->r_end < 1024 * 1024 * 1024) {
+ /*
+ * The first 1Mb is mapped at KERNBASE.
+ */
+ vaddr = (caddr_t)((uintptr_t)KERNBASE + rv->r_start);
+ } else {
+ u_int32_t paddr;
+ u_int32_t psize;
+ u_int32_t poffs;
+
+ paddr = rv->r_start;
+ psize = rv->r_end - rv->r_start;
+
+ poffs = paddr - trunc_page(paddr);
+ vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
+ }
+ rman_set_virtual(rv, vaddr);
+ rman_set_bustag(rv, I386_BUS_SPACE_MEM);
+ rman_set_bushandle(rv, (bus_space_handle_t) vaddr);
+ } else if (type == SYS_RES_IOPORT) {
+ rman_set_bustag(rv, I386_BUS_SPACE_IO);
+ rman_set_bushandle(rv, rv->r_start);
+ }
+ return rv;
+}
+
+static int
+nexus_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_activate_resource(r));
+}
+
+static int
+nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_deactivate_resource(r));
+}
+
+static int
+nexus_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_release_resource(r));
+}
+
+/*
+ * Currently this uses the really grody interface from kern/kern_intr.c
+ * (which really doesn't belong in kern/anything.c). Eventually, all of
+ * the code in kern_intr.c and machdep_intr.c should get moved here, since
+ * this is going to be the official interface.
+ */
+static int
+nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
+ void (*ihand)(void *), void *arg, void **cookiep)
+{
+ intrmask_t *mask;
+ driver_t *driver;
+ int error, icflags;
+
+ if (child)
+ device_printf(child, "interrupting at irq %d\n",
+ (int)irq->r_start);
+
+ *cookiep = 0;
+ if (irq->r_flags & RF_SHAREABLE)
+ icflags = 0;
+ else
+ icflags = INTR_EXCL;
+
+ driver = device_get_driver(child);
+ switch (driver->type) {
+ case DRIVER_TYPE_TTY:
+ mask = &tty_imask;
+ break;
+ case (DRIVER_TYPE_TTY | DRIVER_TYPE_FAST):
+ mask = &tty_imask;
+ icflags |= INTR_FAST;
+ break;
+ case DRIVER_TYPE_BIO:
+ mask = &bio_imask;
+ break;
+ case DRIVER_TYPE_NET:
+ mask = &net_imask;
+ break;
+ case DRIVER_TYPE_CAM:
+ mask = &cam_imask;
+ break;
+ case DRIVER_TYPE_MISC:
+ mask = 0;
+ break;
+ default:
+ panic("still using grody create_intr interface");
+ }
+
+ /*
+ * We depend here on rman_activate_resource() being idempotent.
+ */
+ error = rman_activate_resource(irq);
+ if (error)
+ return (error);
+
+ *cookiep = intr_create((void *)(intptr_t)-1, irq->r_start, ihand, arg,
+ mask, icflags);
+ if (*cookiep)
+ error = intr_connect(*cookiep);
+ else
+ error = EINVAL; /* XXX ??? */
+
+ return (error);
+}
+
+static int
+nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
+{
+ return (intr_destroy(ih));
+}
+
+static devclass_t pcib_devclass;
+
+static int
+nexus_pcib_probe(device_t dev)
+{
+ device_set_desc(dev, "PCI host bus adapter");
+
+ device_add_child(dev, "pci", 0, 0);
+
+ return 0;
+}
+
+static device_method_t nexus_pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_pcib_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t nexus_pcib_driver = {
+ "pcib",
+ nexus_pcib_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+DRIVER_MODULE(pcib, nexus, nexus_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 60cc225..03e74ce 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/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: GENERIC,v 1.160 1999/04/16 16:17:05 n_hibma Exp $
+# $Id: GENERIC,v 1.161 1999/04/16 18:27:18 jkh Exp $
machine "i386"
cpu "I386_CPU"
@@ -53,10 +53,10 @@ 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 eisa0
-controller pci0
+controller isa0 at nexus?
+#controller pnp0 # PnP support for ISA
+#controller eisa0
+controller pci0 at nexus?
controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2
disk fd0 at fdc0 drive 0
@@ -108,9 +108,9 @@ controller matcd0 at isa? port 0x230 bio
device scd0 at isa? port 0x230 bio
# atkbdc0 controlls both the keyboard and the PS/2 mouse
-controller atkbdc0 at isa? port IO_KBD tty
-device atkbd0 at isa? tty irq 1
-device psm0 at isa? tty irq 12
+controller atkbdc0 at isa? port IO_KBD
+device atkbd0 at atkbdc? tty irq 1
+device psm0 at atkbdc? tty irq 12
device vga0 at isa? port ? conflicts
@@ -126,12 +126,12 @@ device sc0 at isa? tty
# If you have a ThinkPAD, uncomment this along with the rest of the PCVT lines
#options PCVT_SCANSET=2 # IBM keyboards are non-std
-device npx0 at isa? port IO_NPX irq 13
+device npx0 at nexus? port IO_NPX irq 13
#
# 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
@@ -178,8 +178,8 @@ device ex0 at isa? port? net irq?
device fe0 at isa? port 0x300 net irq ?
device le0 at isa? port 0x300 net irq 5 iomem 0xd0000
device lnc0 at isa? port 0x280 net irq 10 drq 0
-device ze0 at isa? port 0x300 net irq 10 iomem 0xd8000
-device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000
+#device ze0 at isa? port 0x300 net irq 10 iomem 0xd8000
+#device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000
device cs0 at isa? port 0x300 net irq ?
pseudo-device loop
diff --git a/sys/amd64/isa/intr_machdep.c b/sys/amd64/isa/intr_machdep.c
index 944eb4e..4f7c1e9 100644
--- a/sys/amd64/isa/intr_machdep.c
+++ b/sys/amd64/isa/intr_machdep.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id: intr_machdep.c,v 1.16 1999/01/08 19:17:48 bde Exp $
+ * $Id: intr_machdep.c,v 1.17 1999/04/14 14:26:36 bde Exp $
*/
#include "opt_auto_eoi.h"
@@ -328,6 +328,7 @@ isa_get_nameunit(int id)
return ("clk0"); /* XXX may also be sloppy driver */
if (id == 1)
return ("rtc0");
+#if 0
for (dp = isa_devtab_bio; dp->id_driver != NULL; dp++)
if (dp->id_id == id)
goto found_device;
@@ -343,6 +344,7 @@ isa_get_nameunit(int id)
for (dp = isa_devtab_tty; dp->id_driver != NULL; dp++)
if (dp->id_id == id)
goto found_device;
+#endif
return "???";
found_device:
diff --git a/sys/amd64/isa/isa.c b/sys/amd64/isa/isa.c
index 1e91da8..4b48e36 100644
--- a/sys/amd64/isa/isa.c
+++ b/sys/amd64/isa/isa.c
@@ -1,10 +1,7 @@
/*-
- * Copyright (c) 1991 The Regents of the University of California.
+ * Copyright (c) 1998 Doug Rabson
* 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:
@@ -13,18 +10,11 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -33,1041 +23,601 @@
* 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.c,v 1.117 1998/11/29 15:42:40 phk Exp $
+ * $Id: isa.c,v 1.4 1998/09/16 08:23:51 dfr Exp $
*/
/*
- * code to manage AT bus
+ * Modifications for Intel architecture by Garrett A. Wollman.
+ * Copyright 1998 Massachusetts Institute of Technology
*
- * 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()
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/buf.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
#include <sys/malloc.h>
-#include <machine/ipl.h>
-#include <machine/md_var.h>
-#ifdef APIC_IO
-#include <machine/smp.h>
-#endif /* APIC_IO */
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/intr_machdep.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/ic/i8237.h>
-
-#include <sys/interrupt.h>
-
-#include "pnp.h"
-#if NPNP > 0
-#include <i386/isa/pnp.h>
-#endif
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
-/*
-** Register definitions for DMA controller 1 (channels 0..3):
-*/
-#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 */
+#include <machine/resource.h>
-/*
-** 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 */
+#include <isa/isavar.h>
-static void config_isadev __P((struct isa_device *isdp, u_int *mp));
-static void config_isadev_c __P((struct isa_device *isdp, u_int *mp,
- int reconfig));
-static void conflict __P((struct isa_device *dvp, struct isa_device *tmpdvp,
- int item, char const *whatnot, char const *reason,
- char const *format));
-static int haveseen __P((struct isa_device *dvp, struct isa_device *tmpdvp,
- u_int checkbits));
-static int isa_dmarangecheck __P((caddr_t va, u_int length, int chan));
+MALLOC_DEFINE(M_ISADEV, "isadev", "ISA device");
/*
- * print a conflict message
+ * The structure used to attach devices to the isa bus.
*/
+struct isa_device {
+ short id_port[ISA_NPORT_IVARS];
+ u_short id_portsize[ISA_NPORT_IVARS];
+ vm_offset_t id_maddr[ISA_NMEM_IVARS];
+ vm_size_t id_msize[ISA_NMEM_IVARS];
+ int id_irq[ISA_NIRQ_IVARS];
+ int id_drq[ISA_NDRQ_IVARS];
+ int id_flags;
+ struct resource *id_portres[ISA_NPORT_IVARS];
+ struct resource *id_memres[ISA_NMEM_IVARS];
+ struct resource *id_irqres[ISA_NIRQ_IVARS];
+ struct resource *id_drqres[ISA_NDRQ_IVARS];
+};
+
+#define DEVTOISA(dev) ((struct isa_device *) device_get_ivars(dev))
+
+static devclass_t isa_devclass;
+
static void
-conflict(dvp, tmpdvp, item, whatnot, reason, format)
- struct isa_device *dvp;
- struct isa_device *tmpdvp;
- int item;
- char const *whatnot;
- char const *reason;
- char const *format;
+isa_add_device(device_t dev, const char *name, int unit)
{
- printf("%s%d not %sed due to %s conflict with %s%d at ",
- dvp->id_driver->name, dvp->id_unit, whatnot, reason,
- tmpdvp->id_driver->name, tmpdvp->id_unit);
- printf(format, item);
- printf("\n");
-}
+ struct isa_device *idev;
+ device_t child;
+ int sensitive, t;
+ static device_t last_sensitive;
-/*
- * Check to see if things are already in use, like IRQ's, I/O addresses
- * and Memory addresses.
- */
-static int
-haveseen(dvp, tmpdvp, checkbits)
- struct isa_device *dvp;
- struct isa_device *tmpdvp;
- u_int checkbits;
-{
- /*
- * Ignore all conflicts except IRQ ones if conflicts are allowed.
- */
- if (dvp->id_conflicts)
- checkbits &= ~(CC_DRQ | CC_IOADDR | CC_MEMADDR);
- /*
- * Only check against devices that have already been found.
- */
- if (tmpdvp->id_alive) {
- char const *whatnot;
+ if (resource_int_value(name, unit, "sensitive", &sensitive) != 0)
+ sensitive = 0;
- /*
- * Check for device driver & unit conflict; just drop probing
- * a device which has already probed true. This is usually
- * not strictly a conflict, but rather the case of somebody
- * having specified several mutually exclusive configurations
- * for a single device.
- */
- if (tmpdvp->id_driver == dvp->id_driver &&
- tmpdvp->id_unit == dvp->id_unit) {
- return 1;
- }
+ idev = malloc(sizeof(struct isa_device), M_ISADEV, M_NOWAIT);
+ if (!idev)
+ return;
+ bzero(idev, sizeof *idev);
- whatnot = checkbits & CC_ATTACH ? "attach" : "prob";
- /*
- * Check for I/O address conflict. We can only check the
- * starting address of the device against the range of the
- * device that has already been probed since we do not
- * know how many I/O addresses this device uses.
- */
- if (checkbits & CC_IOADDR && tmpdvp->id_alive != -1) {
- if ((dvp->id_iobase >= tmpdvp->id_iobase) &&
- (dvp->id_iobase <=
- (tmpdvp->id_iobase + tmpdvp->id_alive - 1))) {
- if (!(checkbits & CC_QUIET))
- conflict(dvp, tmpdvp, dvp->id_iobase,
- whatnot, "I/O address", "0x%x");
- return 1;
- }
- }
- /*
- * Check for Memory address conflict. We can check for
- * range overlap, but it will not catch all cases since the
- * driver may adjust the msize paramater during probe, for
- * now we just check that the starting address does not
- * fall within any allocated region.
- * XXX could add a second check after the probe for overlap,
- * since at that time we would know the full range.
- * XXX KERNBASE is a hack, we should have vaddr in the table!
- */
- if (checkbits & CC_MEMADDR && tmpdvp->id_maddr) {
- if ((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) &&
- (KERNBASE + dvp->id_maddr <=
- (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) {
- if (!(checkbits & CC_QUIET))
- conflict(dvp, tmpdvp,
- (int)dvp->id_maddr, whatnot,
- "maddr", "0x%x");
- return 1;
- }
- }
- /*
- * Check for IRQ conflicts.
- */
- if (checkbits & CC_IRQ && tmpdvp->id_irq) {
- if (tmpdvp->id_irq == dvp->id_irq) {
- if (!(checkbits & CC_QUIET))
- conflict(dvp, tmpdvp,
- ffs(dvp->id_irq) - 1, whatnot,
- "irq", "%d");
- return 1;
- }
- }
- /*
- * Check for DRQ conflicts.
- */
- if (checkbits & CC_DRQ && tmpdvp->id_drq != -1) {
- if (tmpdvp->id_drq == dvp->id_drq) {
- if (!(checkbits & CC_QUIET))
- conflict(dvp, tmpdvp, dvp->id_drq,
- whatnot, "drq", "%d");
- return 1;
- }
- }
- }
- return 0;
-}
+ if (resource_int_value(name, unit, "port", &t) == 0)
+ idev->id_port[0] = t;
+ else
+ idev->id_port[0] = -1;
+ idev->id_port[1] = 0;
-#ifdef RESOURCE_CHECK
-#include <sys/drvresource.h>
+ if (resource_int_value(name, unit, "portsize", &t) == 0)
+ idev->id_portsize[0] = t;
+ else
+ idev->id_portsize[0] = 0;
+ idev->id_portsize[1] = 0;
-static int
-checkone (struct isa_device *dvp, int type, addr_t low, addr_t high,
- char *resname, char *resfmt, int attaching)
-{
- int result = 0;
- if (bootverbose) {
- if (low == high)
- printf("\tcheck %s: 0x%x\n", resname, low);
- else
- printf("\tcheck %s: 0x%x to 0x%x\n",
- resname, low, high);
- }
- if (resource_check(type, RESF_NONE, low, high) != NULL) {
- char *whatnot = attaching ? "attach" : "prob";
- static struct isa_device dummydev;
- static struct isa_driver dummydrv;
- struct isa_device *tmpdvp = &dummydev;
+ if (resource_int_value(name, unit, "maddr", &t) == 0)
+ idev->id_maddr[0] = t;
+ else
+ idev->id_maddr[0] = 0;
+ idev->id_maddr[1] = 0;
- dummydev.id_driver = &dummydrv;
- dummydev.id_unit = 0;
- dummydrv.name = "pci";
- conflict(dvp, tmpdvp, low, whatnot, resname, resfmt);
- result = 1;
- } else if (attaching) {
- if (low == high)
- printf("\tregister %s: 0x%x\n", resname, low);
- else
- printf("\tregister %s: 0x%x to 0x%x\n",
- resname, low, high);
- resource_claim(dvp, type, RESF_NONE, low, high);
- }
- return (result);
-}
+ if (resource_int_value(name, unit, "msize", &t) == 0)
+ idev->id_msize[0] = t;
+ else
+ idev->id_msize[0] = 0;
+ idev->id_msize[1] = 0;
-static int
-check_pciconflict(struct isa_device *dvp, int checkbits)
-{
- int result = 0;
- int attaching = (checkbits & CC_ATTACH) != 0;
+ if (resource_int_value(name, unit, "flags", &t) == 0)
+ idev->id_flags = t;
+ else
+ idev->id_flags = 0;
- if (checkbits & CC_MEMADDR) {
- long maddr = dvp->id_maddr;
- long msize = dvp->id_msize;
- if (msize > 0) {
- if (checkone(dvp, REST_MEM, maddr, maddr + msize - 1,
- "maddr", "0x%x", attaching) != 0) {
- result = 1;
- attaching = 0;
- }
- }
- }
- if (checkbits & CC_IOADDR) {
- unsigned iobase = dvp->id_iobase;
- unsigned iosize = dvp->id_alive;
- if (iosize == -1)
- iosize = 1; /* XXX can't do much about this ... */
- if (iosize > 0) {
- if (checkone(dvp, REST_PORT, iobase, iobase + iosize -1,
- "I/O address", "0x%x", attaching) != 0) {
- result = 1;
- attaching = 0;
- }
- }
- }
- if (checkbits & CC_IRQ) {
- int irq = ffs(dvp->id_irq) - 1;
- if (irq >= 0) {
- if (checkone(dvp, REST_INT, irq, irq,
- "irq", "%d", attaching) != 0) {
- result = 1;
- attaching = 0;
- }
- }
- }
- if (checkbits & CC_DRQ) {
- int drq = dvp->id_drq;
- if (drq >= 0) {
- if (checkone(dvp, REST_DMA, drq, drq,
- "drq", "%d", attaching) != 0) {
- result = 1;
- attaching = 0;
- }
- }
- }
- if (result != 0)
- resource_free (dvp);
- return (result);
-}
-#endif /* RESOURCE_CHECK */
+ if (resource_int_value(name, unit, "irq", &t) == 0)
+ idev->id_irq[0] = t;
+ else
+ idev->id_irq[0] = -1;
+ idev->id_irq[1] = -1;
-/*
- * Search through all the isa_devtab_* tables looking for anything that
- * conflicts with the current device.
- */
-int
-haveseen_isadev(dvp, checkbits)
- struct isa_device *dvp;
- u_int checkbits;
-{
-#if NPNP > 0
- struct pnp_dlist_node *nod;
-#endif
- struct isa_device *tmpdvp;
- int status = 0;
+ if (resource_int_value(name, unit, "drq", &t) == 0)
+ idev->id_drq[0] = t;
+ else
+ idev->id_drq[0] = -1;
+ idev->id_drq[1] = -1;
- for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
- for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
- for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
- for (tmpdvp = isa_devtab_cam; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
- for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
-#if NPNP > 0
- for (nod = pnp_device_list; nod != NULL; nod = nod->next)
- if (status |= haveseen(dvp, &(nod->dev), checkbits))
- return status;
-#endif
-#ifdef RESOURCE_CHECK
- if (!dvp->id_conflicts)
- status = check_pciconflict(dvp, checkbits);
- else if (bootverbose)
- printf("\tnot checking for resource conflicts ...\n");
-#endif /* RESOURCE_CHECK */
- return(status);
+ if (sensitive)
+ child = device_add_child_after(dev, last_sensitive, name,
+ unit, idev);
+ else
+ child = device_add_child(dev, name, unit, idev);
+ if (child == 0)
+ return;
+ else if (sensitive)
+ last_sensitive = child;
+
+ if (resource_int_value(name, unit, "disabled", &t) == 0 && t != 0)
+ device_disable(child);
}
/*
- * Configure all ISA devices
+ * At 'probe' time, we add all the devices which we know about to the
+ * bus. The generic attach routine will probe and attach them if they
+ * are alive.
*/
-void
-isa_configure()
+static int
+isa_probe(device_t dev)
{
- struct isa_device *dvp;
+ int i;
+ static char buf[] = "isaXXX";
- printf("Probing for devices on the ISA bus:\n");
- /* First probe all the sensitive probes */
- for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &tty_imask);
- for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &bio_imask);
- for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &net_imask);
- for (dvp = isa_devtab_cam; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &cam_imask);
- for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, (u_int *)NULL);
-
- /* Then all the bad ones */
- for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &tty_imask);
- for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &bio_imask);
- for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &net_imask);
- for (dvp = isa_devtab_cam; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &cam_imask);
- for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, (u_int *)NULL);
-
-/*
- * XXX we should really add the tty device to net_imask when the line is
- * switched to SLIPDISC, and then remove it when it is switched away from
- * SLIPDISC. No need to block out ALL ttys during a splimp when only one
- * of them is running slip.
- *
- * XXX actually, blocking all ttys during a splimp doesn't matter so much
- * with sio because the serial interrupt layer doesn't use tty_imask. Only
- * non-serial ttys suffer. It's more stupid that ALL 'net's are blocked
- * during spltty.
- */
-#include "sl.h"
-#if NSL > 0
- net_imask |= tty_imask;
- tty_imask = net_imask;
-#endif
-
- if (bootverbose)
- printf("imasks: bio %x, tty %x, net %x\n",
- bio_imask, tty_imask, net_imask);
+ device_set_desc(dev, "ISA bus");
/*
- * Finish initializing intr_mask[]. Note that the partly
- * constructed masks aren't actually used since we're at splhigh.
- * For fully dynamic initialization, register_intr() and
- * icu_unset() will have to adjust the masks for _all_
- * interrupts and for tty_imask, etc.
+ * Add all devices configured to be attached to isa0.
*/
- for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
- register_imask(dvp, tty_imask);
- for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
- register_imask(dvp, bio_imask);
- for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
- register_imask(dvp, net_imask);
- for (dvp = isa_devtab_cam; dvp->id_driver; dvp++)
- register_imask(dvp, cam_imask);
- for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
- register_imask(dvp, SWI_CLOCK_MASK);
-}
-
-/*
- * Configure an ISA device.
- */
-static void
-config_isadev(isdp, mp)
- struct isa_device *isdp;
- u_int *mp;
-{
- config_isadev_c(isdp, mp, 0);
-}
-
-void
-reconfig_isadev(isdp, mp)
- struct isa_device *isdp;
- u_int *mp;
-{
- config_isadev_c(isdp, mp, 1);
-}
-
-static void
-config_isadev_c(isdp, mp, reconfig)
- struct isa_device *isdp;
- u_int *mp;
- int reconfig;
-{
- u_int checkbits;
- int id_alive;
- int last_alive;
- struct isa_driver *dp = isdp->id_driver;
-
- if (!isdp->id_enabled) {
- if (bootverbose)
- printf("%s%d: disabled, not probed.\n", dp->name, isdp->id_unit);
- return;
+ sprintf(buf, "isa%d", device_get_unit(dev));
+ for (i = resource_query_string(-1, "at", buf);
+ i != -1;
+ i = resource_query_string(i, "at", buf)) {
+ isa_add_device(dev, resource_query_name(i),
+ resource_query_unit(i));
}
- checkbits = CC_DRQ | CC_IOADDR | CC_MEMADDR;
- if (!reconfig && haveseen_isadev(isdp, checkbits))
- return;
- if (!reconfig && isdp->id_maddr) {
- isdp->id_maddr -= ISA_HOLE_START;
- isdp->id_maddr += atdevbase;
- }
- if (reconfig) {
- last_alive = isdp->id_alive;
- isdp->id_reconfig = 1;
- }
- else {
- last_alive = 0;
- isdp->id_reconfig = 0;
- }
- id_alive = (*dp->probe)(isdp);
- if (id_alive) {
- /*
- * Only print the I/O address range if id_alive != -1
- * Right now this is a temporary fix just for the new
- * NPX code so that if it finds a 486 that can use trap
- * 16 it will not report I/O addresses.
- * Rod Grimes 04/26/94
- */
- if (!isdp->id_reconfig) {
- printf("%s%d", dp->name, isdp->id_unit);
- if (id_alive != -1) {
- if (isdp->id_iobase == -1)
- printf(" at");
- else {
- printf(" at 0x%x", isdp->id_iobase);
- if (isdp->id_iobase + id_alive - 1 !=
- isdp->id_iobase) {
- printf("-0x%x",
- isdp->id_iobase + id_alive - 1);
- }
- }
- }
- if (isdp->id_irq)
- printf(" irq %d", ffs(isdp->id_irq) - 1);
- if (isdp->id_drq != -1)
- printf(" drq %d", isdp->id_drq);
- if (isdp->id_maddr)
- printf(" maddr 0x%lx", kvtop(isdp->id_maddr));
- if (isdp->id_msize)
- printf(" msize %d", isdp->id_msize);
- if (isdp->id_flags)
- printf(" flags 0x%x", isdp->id_flags);
- if (isdp->id_iobase && !(isdp->id_iobase & 0xf300)) {
- printf(" on motherboard");
- } else if (isdp->id_iobase >= 0x1000 &&
- !(isdp->id_iobase & 0x300)) {
- printf (" on eisa slot %d",
- isdp->id_iobase >> 12);
- } else {
- printf (" on isa");
- }
- printf("\n");
- /*
- * Check for conflicts again. The driver may have
- * changed *dvp. We should weaken the early check
- * since the driver may have been able to change
- * *dvp to avoid conflicts if given a chance. We
- * already skip the early check for IRQs and force
- * a check for IRQs in the next group of checks.
- */
- checkbits |= CC_ATTACH | CC_IRQ;
- if (haveseen_isadev(isdp, checkbits))
- return;
- isdp->id_alive = id_alive;
- }
- (*dp->attach)(isdp);
- if (isdp->id_irq != 0 && isdp->id_intr == NULL)
- printf("%s%d: irq with no handler\n",
- dp->name, isdp->id_unit);
- if (isdp->id_irq != 0 && isdp->id_intr != NULL) {
-#ifdef APIC_IO
- /*
- * Some motherboards use upper IRQs for traditional
- * ISA INTerrupt sources. In particular we have
- * seen the secondary IDE connected to IRQ20.
- * This code detects and fixes this situation.
- */
- u_int apic_mask;
- int rirq;
- apic_mask = isa_apic_mask(isdp->id_irq);
- if (apic_mask != isdp->id_irq) {
- rirq = ffs(isdp->id_irq) - 1;
- isdp->id_irq = apic_mask;
- undirect_isa_irq(rirq); /* free for ISA */
- }
-#endif /* APIC_IO */
- register_intr(ffs(isdp->id_irq) - 1, isdp->id_id,
- isdp->id_ri_flags, isdp->id_intr,
- mp, isdp->id_unit);
- }
- } else {
- if (isdp->id_reconfig) {
- (*dp->attach)(isdp); /* reconfiguration attach */
- }
- if (!last_alive) {
- if (!isdp->id_reconfig) {
- printf("%s%d not found",
- dp->name, isdp->id_unit);
- if (isdp->id_iobase != -1)
- printf(" at 0x%x", isdp->id_iobase);
- printf("\n");
- }
- } else {
-#if 0
- /* This code has not been tested.... */
- if (isdp->id_irq != 0 && isdp->id_intr != NULL) {
- icu_unset(ffs(isdp->id_irq) - 1,
- isdp->id_intr);
- if (mp)
- INTRUNMASK(*mp, isdp->id_irq);
- }
-#else
- printf ("icu_unset() not supported here ...\n");
-#endif
- }
+ /*
+ * and isa?
+ */
+ for (i = resource_query_string(-1, "at", "isa");
+ i != -1;
+ i = resource_query_string(i, "at", "isa")) {
+ isa_add_device(dev, resource_query_name(i),
+ resource_query_unit(i));
}
-}
-static caddr_t dma_bouncebuf[8];
-static u_int dma_bouncebufsize[8];
-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;
+ isa_wrap_old_drivers();
-#define VALID_DMA_MASK (7)
+ return 0;
+}
-/* high byte of address is stored in this port for i-th dma channel */
-static int dmapageport[8] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
+extern device_t isa_bus_device;
-/*
- * Setup a DMA channel's bounce buffer.
- */
-void
-isa_dmainit(chan, bouncebufsize)
- int chan;
- u_int bouncebufsize;
+static int
+isa_attach(device_t dev)
{
- 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;
+ /*
+ * Arrange for bus_generic_attach(dev) to be called later.
+ */
+ isa_bus_device = dev;
+ return 0;
}
-/*
- * Register a DMA channel's usage. Usually called from a device driver
- * in open() or during its initialization.
- */
-int
-isa_dma_acquire(chan)
- int chan;
+static void
+isa_print_child(device_t bus, device_t dev)
{
-#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);
+ struct isa_device *id = DEVTOISA(dev);
+
+ if (id->id_port[0] > 0 || id->id_port[1] > 0
+ || id->id_maddr[0] > 0 || id->id_maddr[1] > 0
+ || id->id_irq[0] >= 0 || id->id_irq[1] >= 0
+ || id->id_drq[0] >= 0 || id->id_drq[1] >= 0)
+ printf(" at");
+ if (id->id_port[0] > 0 && id->id_port[1] > 0) {
+ printf(" ports %#x", (u_int)id->id_port[0]);
+ if (id->id_portsize[0] > 1)
+ printf("-%#x", (u_int)(id->id_port[0]
+ + id->id_portsize[0] - 1));
+ printf(" and %#x", (u_int)id->id_port[1]);
+ if (id->id_portsize[1] > 1)
+ printf("-%#x", (u_int)(id->id_port[1]
+ + id->id_portsize[1] - 1));
+ } else if (id->id_port[0] > 0) {
+ printf(" port %#x", (u_int)id->id_port[0]);
+ if (id->id_portsize[0] > 1)
+ printf("-%#x", (u_int)(id->id_port[0]
+ + id->id_portsize[0] - 1));
+ } else if (id->id_port[1] > 0) {
+ printf(" port %#x", (u_int)id->id_port[1]);
+ if (id->id_portsize[1] > 1)
+ printf("-%#x", (u_int)(id->id_port[1]
+ + id->id_portsize[1] - 1));
+ }
+ if (id->id_maddr[0] && id->id_maddr[1]) {
+ printf(" iomem %#x", (u_int)id->id_maddr[0]);
+ if (id->id_msize[0])
+ printf("-%#x", (u_int)(id->id_maddr[0]
+ + id->id_msize[0] - 1));
+ printf(" and %#x", (u_int)id->id_maddr[1]);
+ if (id->id_msize[1])
+ printf("-%#x", (u_int)(id->id_maddr[1]
+ + id->id_msize[1] - 1));
+ } else if (id->id_maddr[0]) {
+ printf(" iomem %#x", (u_int)id->id_maddr[0]);
+ if (id->id_msize[0])
+ printf("-%#x", (u_int)(id->id_maddr[0]
+ + id->id_msize[0] - 1));
+ } else if (id->id_maddr[1]) {
+ printf(" iomem %#x", (u_int)id->id_maddr[1]);
+ if (id->id_msize[1])
+ printf("-%#x", (u_int)(id->id_maddr[1]
+ + id->id_msize[1] - 1));
+ }
+ if (id->id_irq[0] >= 0 && id->id_irq[1] >= 0)
+ printf(" irqs %d and %d", id->id_irq[0], id->id_irq[1]);
+ else if (id->id_irq[0] >= 0)
+ printf(" irq %d", id->id_irq[0]);
+ else if (id->id_irq[1] >= 0)
+ printf(" irq %d", id->id_irq[1]);
+ if (id->id_drq[0] >= 0 && id->id_drq[1] >= 0)
+ printf(" drqs %d and %d", id->id_drq[0], id->id_drq[1]);
+ else if (id->id_drq[0] >= 0)
+ printf(" drq %d", id->id_drq[0]);
+ else if (id->id_drq[1] >= 0)
+ printf(" drq %d", id->id_drq[1]);
+
+ if (id->id_flags)
+ printf(" flags %#x", id->id_flags);
+
+ printf(" on %s%d",
+ device_get_name(bus), device_get_unit(bus));
}
-/*
- * 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;
+static int
+isa_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result)
{
-#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);
+ struct isa_device* idev = DEVTOISA(dev);
+
+ switch (index) {
+ case ISA_IVAR_PORT_0:
+ *result = idev->id_port[0];
+ break;
+ case ISA_IVAR_PORT_1:
+ *result = idev->id_port[1];
+ break;
+ case ISA_IVAR_PORTSIZE_0:
+ *result = idev->id_portsize[0];
+ break;
+ case ISA_IVAR_PORTSIZE_1:
+ *result = idev->id_portsize[1];
+ break;
+ case ISA_IVAR_MADDR_0:
+ *result = idev->id_maddr[0];
+ break;
+ case ISA_IVAR_MADDR_1:
+ *result = idev->id_maddr[1];
+ break;
+ case ISA_IVAR_MSIZE_0:
+ *result = idev->id_msize[0];
+ break;
+ case ISA_IVAR_MSIZE_1:
+ *result = idev->id_msize[1];
+ break;
+ case ISA_IVAR_IRQ_0:
+ *result = idev->id_irq[0];
+ break;
+ case ISA_IVAR_IRQ_1:
+ *result = idev->id_irq[1];
+ break;
+ case ISA_IVAR_DRQ_0:
+ *result = idev->id_drq[0];
+ break;
+ case ISA_IVAR_DRQ_1:
+ *result = idev->id_drq[1];
+ break;
+ case ISA_IVAR_FLAGS:
+ *result = idev->id_flags;
+ break;
+ }
+ return ENOENT;
}
/*
- * isa_dmacascade(): program 8237 DMA controller channel to accept
- * external dma control by a board.
+ * XXX -- this interface is pretty much irrelevant in the presence of
+ * BUS_ALLOC_RESOURCE / BUS_RELEASE_RESOURCE (at least for the ivars which
+ * are defined at this point).
*/
-void
-isa_dmacascade(chan)
- int chan;
+static int
+isa_write_ivar(device_t bus, device_t dev,
+ int index, uintptr_t value)
{
-#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);
+ struct isa_device* idev = DEVTOISA(dev);
+
+ switch (index) {
+ case ISA_IVAR_PORT_0:
+ idev->id_port[0] = value;
+ break;
+ case ISA_IVAR_PORT_1:
+ idev->id_port[1] = value;
+ break;
+ case ISA_IVAR_PORTSIZE_0:
+ idev->id_portsize[0] = value;
+ break;
+ case ISA_IVAR_PORTSIZE_1:
+ idev->id_portsize[1] = value;
+ break;
+ case ISA_IVAR_MADDR_0:
+ idev->id_maddr[0] = value;
+ break;
+ case ISA_IVAR_MADDR_1:
+ idev->id_maddr[1] = value;
+ break;
+ case ISA_IVAR_MSIZE_0:
+ idev->id_msize[0] = value;
+ break;
+ case ISA_IVAR_MSIZE_1:
+ idev->id_msize[1] = value;
+ break;
+ case ISA_IVAR_IRQ_0:
+ idev->id_irq[0] = value;
+ break;
+ case ISA_IVAR_IRQ_1:
+ idev->id_irq[1] = value;
+ break;
+ case ISA_IVAR_DRQ_0:
+ idev->id_drq[0] = value;
+ break;
+ case ISA_IVAR_DRQ_1:
+ idev->id_drq[1] = value;
+ break;
+ case ISA_IVAR_FLAGS:
+ idev->id_flags = value;
+ break;
+ default:
+ return (ENOENT);
}
+ return (0);
}
/*
- * isa_dmastart(): program 8237 DMA controller channel, avoid page alignment
- * problems by using a bounce buffer.
+ * This implementation simply passes the request up to the parent
+ * bus, which in our case is the special i386 nexus, substituting any
+ * configured values if the caller defaulted. We can get away with
+ * this because there is no special mapping for ISA resources on an Intel
+ * platform. When porting this code to another architecture, it may be
+ * necessary to interpose a mapping layer here.
*/
-void
-isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
+static struct resource *
+isa_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
{
- vm_offset_t phys;
- int waport;
- caddr_t newaddr;
+ int isdefault;
+ struct resource *rv, **rvp = 0;
+ struct isa_device *id = DEVTOISA(child);
-#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);
- }
-
- if ((chan & 4) == 0) {
+ if (child) {
/*
- * Program one of DMA channels 0..3. These are
- * byte mode channels.
+ * If this is our child, then use the isa_device to find
+ * defaults and to record results.
*/
- /* 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);
+ if (device_get_devclass(device_get_parent(child)) == isa_devclass)
+ id = DEVTOISA(child);
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);
- } 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));
+ id = NULL;
+ } else
+ id = NULL;
+ isdefault = (id != NULL && start == 0UL && end == ~0UL && *rid == 0);
+ if (*rid > 1)
+ return 0;
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (isdefault && id->id_irq[0] >= 0) {
+ start = id->id_irq[0];
+ end = id->id_irq[0];
+ count = 1;
}
- 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);
+ if (id)
+ rvp = &id->id_irqres[*rid];
+ break;
+
+ case SYS_RES_DRQ:
+ if (isdefault && id->id_drq[0] >= 0) {
+ start = id->id_drq[0];
+ end = id->id_drq[0];
+ count = 1;
+ }
+ if (id)
+ rvp = &id->id_drqres[*rid];
+ break;
+
+ case SYS_RES_MEMORY:
+ if (isdefault && id->id_maddr[0]) {
+ start = id->id_maddr[0];
+ count = max(count, (u_long)id->id_msize[0]);
+ end = id->id_maddr[0] + count;
+ }
+ if (id)
+ rvp = &id->id_memres[*rid];
+ break;
+
+ case SYS_RES_IOPORT:
+ if (isdefault && id->id_port[0]) {
+ start = id->id_port[0];
+ count = max(count, (u_long)id->id_portsize[0]);
+ end = id->id_port[0] + count;
+ }
+ if (id)
+ rvp = &id->id_portres[*rid];
+ break;
- /* unmask channel */
- outb(DMA2_SMSK, chan & 3);
+ default:
+ return 0;
}
-}
-
-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);
- if ((dma_auto_mode & (1 << chan)) == 0)
- outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
-
- if (dma_bounced & (1 << chan)) {
- /* copy bounce buffer on read */
- if (flags & B_READ)
- bcopy(dma_bouncebuf[chan], addr, nbytes);
+ /*
+ * If the client attempts to reallocate a resource without
+ * releasing what was there previously, die horribly so that
+ * he knows how he !@#$ed up.
+ */
+ if (rvp && *rvp != 0)
+ panic("%s%d: (%d, %d) not free for %s%d\n",
+ device_get_name(bus), device_get_unit(bus),
+ type, *rid,
+ device_get_name(child), device_get_unit(child));
- dma_bounced &= ~(1 << chan);
+ /*
+ * nexus_alloc_resource had better not change *rid...
+ */
+ rv = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid,
+ start, end, count, flags);
+ if (rvp && (*rvp = rv) != 0) {
+ switch (type) {
+ case SYS_RES_MEMORY:
+ id->id_maddr[*rid] = rv->r_start;
+ id->id_msize[*rid] = count;
+ break;
+ case SYS_RES_IOPORT:
+ id->id_port[*rid] = rv->r_start;
+ id->id_portsize[*rid] = count;
+ break;
+ case SYS_RES_IRQ:
+ id->id_irq[*rid] = rv->r_start;
+ break;
+ case SYS_RES_DRQ:
+ id->id_drq[*rid] = rv->r_start;
+ break;
+ }
}
- dma_busy &= ~(1 << chan);
+ return rv;
}
-/*
- * 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)
+isa_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
{
- 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));
-#define ISARAM_END RAM_END
- 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);
-}
+ int rv;
+ struct isa_device *id = DEVTOISA(child);
-/*
- * 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;
+ if (rid > 1)
+ return EINVAL;
- /* channel active? */
- if ((dma_inuse & (1 << chan)) == 0) {
- printf("isa_dmastatus: channel %d not active\n", chan);
- return(-1);
+ switch (type) {
+ case SYS_RES_IRQ:
+ case SYS_RES_DRQ:
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+ break;
+ default:
+ return (ENOENT);
}
- /* channel busy? */
- if (((dma_busy & (1 << chan)) == 0) &&
- (dma_auto_mode & (1 << chan)) == 0 ) {
- printf("chan %d not busy\n", chan);
- return -2 ;
- }
- 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;
- }
+ rv = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, type, rid, r);
- 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 */
+#if 0
+ if (rv) {
+ /* Kludge, isa as a child of pci doesn't have mapping regs */
+ printf("WARNING: isa_release_resource: BUS_RELEASE_RESOURCE() failed: %d\n", rv);
+ rv = 0;
+ }
+#endif
- /*
- * 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 (rv == 0) {
+ switch (type) {
+ case SYS_RES_IRQ:
+ id->id_irqres[rid] = 0;
+ id->id_irq[rid] = -1;
+ break;
+
+ case SYS_RES_DRQ:
+ id->id_drqres[rid] = 0;
+ id->id_drq[rid] = -1;
+ break;
+
+ case SYS_RES_MEMORY:
+ id->id_memres[rid] = 0;
+ id->id_maddr[rid] = 0;
+ id->id_msize[rid] = 0;
+ break;
+
+ case SYS_RES_IOPORT:
+ id->id_portres[rid] = 0;
+ id->id_port[rid] = 0;
+ id->id_portsize[rid] = 0;
+ break;
+
+ default:
+ return ENOENT;
+ }
}
- if (chan >= 4) /* high channels move words */
- cnt *= 2;
- return(cnt);
+ return rv;
}
/*
- * Stop a DMA transfer currently in progress.
+ * We can't use the bus_generic_* versions of these methods because those
+ * methods always pass the bus param as the requesting device, and we need
+ * to pass the child (the i386 nexus knows about this and is prepared to
+ * deal).
*/
-int
-isa_dmastop(int chan)
+static int
+isa_setup_intr(device_t bus, device_t child, struct resource *r,
+ void (*ihand)(void *), void *arg, void **cookiep)
{
- 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 {
- outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
- }
- return(isa_dmastatus(chan));
+ return (BUS_SETUP_INTR(device_get_parent(bus), child, r, ihand, arg,
+ cookiep));
}
-/*
- * Find the highest priority enabled display device. Since we can't
- * distinguish display devices from ttys, depend on display devices
- * being sensitive and before sensitive non-display devices (if any)
- * in isa_devtab_tty.
- *
- * XXX we should add capability flags IAMDISPLAY and ISUPPORTCONSOLES.
- */
-struct isa_device *
-find_display()
+static int
+isa_teardown_intr(device_t bus, device_t child, struct resource *r,
+ void *cookie)
{
- struct isa_device *dvp;
-
- for (dvp = isa_devtab_tty; dvp->id_driver != NULL; dvp++)
- if (dvp->id_driver->sensitive_hw && dvp->id_enabled)
- return (dvp);
- return (NULL);
+ return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, cookie));
}
+static device_method_t isa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, isa_probe),
+ DEVMETHOD(device_attach, isa_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),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, isa_print_child),
+ DEVMETHOD(bus_read_ivar, isa_read_ivar),
+ DEVMETHOD(bus_write_ivar, isa_write_ivar),
+ DEVMETHOD(bus_alloc_resource, isa_alloc_resource),
+ DEVMETHOD(bus_release_resource, isa_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, isa_setup_intr),
+ DEVMETHOD(bus_teardown_intr, isa_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t isa_driver = {
+ "isa",
+ isa_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+
/*
- * find an ISA device in a given isa_devtab_* table, given
- * the table to search, the expected id_driver entry, and the unit number.
- *
- * this function is defined in isa_device.h, and this location is debatable;
- * i put it there because it's useless w/o, and directly operates on
- * the other stuff in that file.
- *
+ * ISA can be attached to a PCI-ISA bridge or directly to the nexus.
*/
-
-struct isa_device *
-find_isadev(table, driverp, unit)
- struct isa_device *table;
- struct isa_driver *driverp;
- int unit;
-{
- if (driverp == NULL) /* sanity check */
- return (NULL);
-
- while ((table->id_driver != driverp) || (table->id_unit != unit)) {
- if (table->id_driver == 0)
- return NULL;
-
- table++;
- }
-
- return (table);
-}
+DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0);
+DRIVER_MODULE(isa, nexus, isa_driver, isa_devclass, 0, 0);
diff --git a/sys/amd64/isa/isa_dma.c b/sys/amd64/isa/isa_dma.c
new file mode 100644
index 0000000..abea7f8
--- /dev/null
+++ b/sys/amd64/isa/isa_dma.c
@@ -0,0 +1,510 @@
+/*-
+ * 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.c,v 1.117 1998/11/29 15:42:40 phk 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()
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <machine/ipl.h>
+#include <machine/md_var.h>
+#ifdef APIC_IO
+#include <machine/smp.h>
+#endif /* APIC_IO */
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <i386/isa/isa_device.h>
+#include <i386/isa/intr_machdep.h>
+#include <i386/isa/isa.h>
+#include <i386/isa/ic/i8237.h>
+
+#include <sys/interrupt.h>
+
+#include "pnp.h"
+#if NPNP > 0
+#include <i386/isa/pnp.h>
+#endif
+
+/*
+** Register definitions for DMA controller 1 (channels 0..3):
+*/
+#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 */
+
+/*
+** 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));
+
+static caddr_t dma_bouncebuf[8];
+static u_int dma_bouncebufsize[8];
+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;
+
+#define VALID_DMA_MASK (7)
+
+/* high byte of address is stored in this port for i-th dma channel */
+static int dmapageport[8] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
+
+/*
+ * 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);
+}
+
+/*
+ * 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);
+ }
+}
+
+/*
+ * 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);
+ }
+
+ if ((chan & 4) == 0) {
+ /*
+ * Program one of DMA channels 0..3. These are
+ * byte 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(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);
+ } 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);
+ }
+}
+
+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);
+
+ if ((dma_auto_mode & (1 << chan)) == 0)
+ outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
+
+ 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));
+#define ISARAM_END RAM_END
+ 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 ;
+ }
+ 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;
+ }
+
+ 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 {
+ outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
+ }
+ return(isa_dmastatus(chan));
+}
diff --git a/sys/amd64/isa/isa_dma.h b/sys/amd64/isa/isa_dma.h
new file mode 100644
index 0000000..3fe234c
--- /dev/null
+++ b/sys/amd64/isa/isa_dma.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91
+ * $Id: isa_device.h,v 1.57 1999/01/17 06:33:43 bde Exp $
+ */
+
+#ifndef _I386_ISA_ISA_DMA_H_
+#define _I386_ISA_ISA_DMA_H_
+
+#ifdef KERNEL
+void isa_dmacascade __P((int chan));
+void isa_dmadone __P((int flags, caddr_t addr, int nbytes, int chan));
+void isa_dmainit __P((int chan, u_int bouncebufsize));
+void isa_dmastart __P((int flags, caddr_t addr, u_int nbytes, int chan));
+int isa_dma_acquire __P((int chan));
+void isa_dma_release __P((int chan));
+int isa_dmastatus __P((int chan));
+int isa_dmastop __P((int chan));
+#endif /* KERNEL */
+
+#endif /* !_I386_ISA_ISA_DMA_H_ */
diff --git a/sys/amd64/isa/nmi.c b/sys/amd64/isa/nmi.c
index 944eb4e..4f7c1e9 100644
--- a/sys/amd64/isa/nmi.c
+++ b/sys/amd64/isa/nmi.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id: intr_machdep.c,v 1.16 1999/01/08 19:17:48 bde Exp $
+ * $Id: intr_machdep.c,v 1.17 1999/04/14 14:26:36 bde Exp $
*/
#include "opt_auto_eoi.h"
@@ -328,6 +328,7 @@ isa_get_nameunit(int id)
return ("clk0"); /* XXX may also be sloppy driver */
if (id == 1)
return ("rtc0");
+#if 0
for (dp = isa_devtab_bio; dp->id_driver != NULL; dp++)
if (dp->id_id == id)
goto found_device;
@@ -343,6 +344,7 @@ isa_get_nameunit(int id)
for (dp = isa_devtab_tty; dp->id_driver != NULL; dp++)
if (dp->id_id == id)
goto found_device;
+#endif
return "???";
found_device:
diff --git a/sys/amd64/isa/npx.c b/sys/amd64/isa/npx.c
index 2371e7b..dc2eb73 100644
--- a/sys/amd64/isa/npx.c
+++ b/sys/amd64/isa/npx.c
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
- * $Id: npx.c,v 1.65 1999/01/08 16:29:59 bde Exp $
+ * $Id: npx.c,v 1.66 1999/03/28 23:28:18 dt Exp $
*/
#include "npx.h"
@@ -43,10 +43,14 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
#ifdef NPX_DEBUG
#include <sys/syslog.h>
#endif
@@ -64,6 +68,7 @@
#ifndef SMP
#include <machine/clock.h>
#endif
+#include <machine/resource.h>
#include <machine/specialreg.h>
#include <machine/segments.h>
@@ -72,7 +77,6 @@
#include <i386/isa/intr_machdep.h>
#include <i386/isa/isa.h>
#endif
-#include <i386/isa/isa_device.h>
/*
* 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
@@ -83,9 +87,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)))
@@ -119,18 +120,15 @@ 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));
+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,
@@ -191,12 +189,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 */
@@ -213,20 +212,20 @@ 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;
+ npx_intrno = NRSVIDT + 13;
save_eflags = read_eflags();
disable_intr();
save_icu1_mask = inb(IO_ICU1 + 1);
save_icu2_mask = inb(IO_ICU2 + 1);
save_idt_npxintr = idt[npx_intrno];
save_idt_npxtrap = idt[16];
- 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)));
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();
outb(IO_ICU1 + 1, save_icu1_mask);
outb(IO_ICU2 + 1, save_icu2_mask);
@@ -239,8 +238,8 @@ npxprobe(dvp)
}
static int
-npxprobe1(dvp)
- struct isa_device *dvp;
+npx_probe1(dev)
+ device_t dev;
{
#ifndef SMP
u_short control;
@@ -280,21 +279,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.
@@ -335,14 +331,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.
*/
@@ -350,8 +344,30 @@ npxprobe1(dvp)
/*
* npxattach would be too late to set npx0_imask.
*/
- npx0_imask |= dvp->id_irq;
- return (IO_NPXSIZE);
+ npx0_imask |= (1 << 13);
+
+ /*
+ * 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;
+ r = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &rid, 13, 13,
+ 1, RF_ACTIVE);
+ 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.
@@ -363,13 +379,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 */
}
@@ -377,14 +387,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)
@@ -401,23 +412,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 */
}
/*
@@ -494,8 +508,8 @@ npxexit(p)
* solution for signals other than SIGFPE.
*/
void
-npxintr(unit)
- int unit;
+npx_intr(dummy)
+ void *dummy;
{
int code;
struct intrframe *frame;
@@ -518,7 +532,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
@@ -686,4 +700,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/boot/alpha/boot1/boot1.c b/sys/boot/alpha/boot1/boot1.c
index 9eac7ec..7346c5b 100644
--- a/sys/boot/alpha/boot1/boot1.c
+++ b/sys/boot/alpha/boot1/boot1.c
@@ -1,5 +1,5 @@
/*
- * $Id: boot1.c,v 1.2 1998/09/26 10:51:36 dfr Exp $
+ * $Id: boot1.c,v 1.3 1998/10/18 19:05:07 dfr Exp $
* From $NetBSD: bootxx.c,v 1.4 1997/09/06 14:08:29 drochner Exp $
*/
@@ -49,6 +49,18 @@ putchar(int c)
prom_putchar(c);
}
+int
+getchar()
+{
+ return prom_getchar();
+}
+
+int
+ischar()
+{
+ return prom_poll();
+}
+
void
puts(const char *s)
{
@@ -150,9 +162,37 @@ devclose()
}
void
+getfilename(char *filename)
+{
+ int c;
+ char *p;
+
+ puts("Boot: ");
+
+ while ((c = getchar()) != '\n') {
+ if (c == '\b') {
+ if (p > filename) {
+ puts("\b \b");
+ p--;
+ }
+ } else
+ *p++ = c;
+ }
+ *p = '\0';
+ return;
+}
+
+void
loadfile(char *name, char *addr)
{
int n;
+ char filename[512];
+ char *p;
+
+ restart:
+ puts("Loading ");
+ puts(name);
+ puts("\n");
if (openrd(name)) {
puts("Can't open file ");
@@ -161,9 +201,17 @@ loadfile(char *name, char *addr)
halt();
}
+ p = addr;
do {
- n = readit(addr, 1024);
- addr += n;
+ n = readit(p, 1024);
+ p += n;
+ if (ischar()) {
+ puts("Stop!\n");
+ devclose();
+ getfilename(filename);
+ name = filename;
+ goto restart;
+ }
twiddle();
} while (n > 0);
diff --git a/sys/boot/alpha/libalpha/prom.c b/sys/boot/alpha/libalpha/prom.c
index 535ce31..380326c 100644
--- a/sys/boot/alpha/libalpha/prom.c
+++ b/sys/boot/alpha/libalpha/prom.c
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: prom.c,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $ */
/* $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ */
/*
@@ -41,7 +41,7 @@ static void prom_probe(struct console *cp);
static int prom_init(int);
void prom_putchar(int);
int prom_getchar(void);
-static int prom_poll(void);
+int prom_poll(void);
struct console promconsole = {
"prom",
diff --git a/sys/boot/alpha/libalpha/start.S b/sys/boot/alpha/libalpha/start.S
index 39c3e48..f42b5da 100644
--- a/sys/boot/alpha/libalpha/start.S
+++ b/sys/boot/alpha/libalpha/start.S
@@ -1,5 +1,5 @@
/*
- * $Id: start.S,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $
+ * $Id: start.S,v 1.2 1998/10/31 17:12:32 dfr Exp $
* From: $NetBSD: start.S,v 1.4 1998/03/28 00:54:15 cgd Exp $
*/
@@ -45,6 +45,7 @@
.set noreorder /* don't reorder instructions */
#define ENTRY_FRAME 32
+#define STACK_SIZE 8192
NESTED(start, 1, ENTRY_FRAME, ra, 0, 0)
br pv,Lstartgp
@@ -57,7 +58,7 @@ Lstartgp:
CALL(bzero)
#if defined(NETBOOT) || defined(LOADER)
- lda sp,stack + 8192 - ENTRY_FRAME
+ lda sp,stack + STACK_SIZE - ENTRY_FRAME
#endif
CALL(main) /* transfer to C */
@@ -84,5 +85,5 @@ LEAF(cpu_number, 0)
END(cpu_number)
#if defined(NETBOOT) || defined(LOADER)
-BSS(stack, 8192)
+BSS(stack, STACK_SIZE)
#endif
diff --git a/sys/boot/alpha/netboot/Makefile b/sys/boot/alpha/netboot/Makefile
index 927522c..4643add 100644
--- a/sys/boot/alpha/netboot/Makefile
+++ b/sys/boot/alpha/netboot/Makefile
@@ -15,6 +15,7 @@ SRCS+= main.c conf.c dev_net.c
.include <${.CURDIR}/../../common/Makefile.inc>
CFLAGS+= -mno-fp-regs
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}
+CFLAGS+= -I${.CURDIR}/../../.. -I.
CFLAGS+= -I${.OBJDIR}
CFLAGS+= -DNETBOOT
diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h
index 996c07e..b405ac7 100644
--- a/sys/boot/common/bootstrap.h
+++ b/sys/boot/common/bootstrap.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bootstrap.h,v 1.19 1999/01/22 23:50:13 msmith Exp $
+ * $Id: bootstrap.h,v 1.20 1999/02/04 17:06:45 dcs Exp $
*/
#include <sys/types.h>
@@ -214,8 +214,8 @@ extern int elf_loadmodule(char *filename, vm_offset_t dest, struct loaded_module
/* XXX just for conversion's sake, until we move to the new linker set code */
#define SET_FOREACH(pvar, set) \
- for (pvar = set.ls_items; \
- pvar < set.ls_items + set.ls_length; \
+ for ((char*) pvar = set.ls_items; \
+ (char*) pvar < (char*) &set.ls_items[set.ls_length]; \
pvar++)
#else /* NEW_LINKER_SET */
diff --git a/sys/boot/ofw/libofw/ofw_console.c b/sys/boot/ofw/libofw/ofw_console.c
index 535ce31..380326c 100644
--- a/sys/boot/ofw/libofw/ofw_console.c
+++ b/sys/boot/ofw/libofw/ofw_console.c
@@ -1,4 +1,4 @@
-/* $Id$ */
+/* $Id: prom.c,v 1.1.1.1 1998/08/21 03:17:42 msmith Exp $ */
/* $NetBSD: prom.c,v 1.3 1997/09/06 14:03:58 drochner Exp $ */
/*
@@ -41,7 +41,7 @@ static void prom_probe(struct console *cp);
static int prom_init(int);
void prom_putchar(int);
int prom_getchar(void);
-static int prom_poll(void);
+int prom_poll(void);
struct console promconsole = {
"prom",
diff --git a/sys/conf/Makefile.i386 b/sys/conf/Makefile.i386
index 9c9ba23..cf6a212 100644
--- a/sys/conf/Makefile.i386
+++ b/sys/conf/Makefile.i386
@@ -1,7 +1,7 @@
# Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.i386,v 1.144 1999/04/13 18:25:08 peter Exp $
+# $Id: Makefile.i386,v 1.145 1999/04/15 14:52:23 bde Exp $
#
# Makefile for FreeBSD
#
@@ -17,7 +17,7 @@
#
# Which version of config(8) is required.
-%VERSREQ= 300012
+%VERSREQ= 400013
KERNFORMAT?= elf
diff --git a/sys/conf/Makefile.powerpc b/sys/conf/Makefile.powerpc
index 9c9ba23..cf6a212 100644
--- a/sys/conf/Makefile.powerpc
+++ b/sys/conf/Makefile.powerpc
@@ -1,7 +1,7 @@
# Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.i386,v 1.144 1999/04/13 18:25:08 peter Exp $
+# $Id: Makefile.i386,v 1.145 1999/04/15 14:52:23 bde Exp $
#
# Makefile for FreeBSD
#
@@ -17,7 +17,7 @@
#
# Which version of config(8) is required.
-%VERSREQ= 300012
+%VERSREQ= 400013
KERNFORMAT?= elf
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 833fbc9..20b284b 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.581 1999/04/14 16:54:00 peter Exp $
+# $Id: LINT,v 1.582 1999/04/16 16:17:04 n_hibma Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -827,7 +827,7 @@ options "MSGBUF_SIZE=40960"
#
# Mandatory ISA devices: isa, npx
#
-controller isa0
+controller isa0 at nexus?
#
# Options for `isa':
@@ -888,10 +888,10 @@ options "NTIMECOUNTER=20"
controller pnp0
# The keyboard controller; it controlls the keyboard and the PS/2 mouse.
-controller atkbdc0 at isa? port IO_KBD tty
+controller atkbdc0 at isa? port IO_KBD
# The AT keyboard
-device atkbd0 at isa? tty irq 1
+device atkbd0 at atkbdc? tty irq 1
# Options for atkbd:
options ATKBD_DFLT_KEYMAP # specify the built-in keymap
@@ -907,7 +907,7 @@ options KBD_INSTALL_CDEV # install a CDEV entry in /dev
# 0x04 Old-style (XT) keyboard support, useful for older ThinkPads
# PS/2 mouse
-device psm0 at isa? tty irq 12
+device psm0 at atkbdc? tty irq 12
# Options for psm:
options PSM_HOOKAPM #hook the APM resume event, useful
@@ -977,7 +977,7 @@ options SC_DISABLE_REBOOT # disable reboot key sequence
# buggy. If it is not configured then you *must* configure math emulation
# (see above). If both npx0 and emulation are configured, then only npx0
# is used (provided it works).
-device npx0 at isa? port IO_NPX iosiz 0x0 flags 0x0 irq 13
+device npx0 at nexus? port IO_NPX iosiz 0x0 flags 0x0 irq 13
#
# `flags' for npx0:
@@ -1464,7 +1464,7 @@ controller matcd0 at isa? port 0x230 bio
device wt0 at isa? port 0x300 bio irq 5 drq 1
device ctx0 at isa? port 0x230 iomem 0xd0000
device spigot0 at isa? port 0xad6 irq 15 iomem 0xee000
-device apm0 at isa?
+device apm0 at nexus?
device gp0 at isa? port 0x2c0 tty
device gsc0 at isa? port "IO_GSC1" tty drq 3
device joy0 at isa? port IO_GAME
@@ -1632,7 +1632,7 @@ options "EISA_SLOTS=12"
# The "oltr" driver supports the following Olicom PCI token-ring adapters
# OC-3136, OC-3137, OC-3139, OC-3140, OC-3141, OC-3540, OC-3250
#
-controller pci0
+controller pci0 at nexus?
controller ahc1
controller ncr0
controller isp0
diff --git a/sys/conf/files b/sys/conf/files
index 66e94b0..7987e0a 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -613,6 +613,21 @@ pci/ncr.c optional ncr device-driver
pci/pci.c optional pci device-driver
pci/pci_compat.c optional pci
pci/pcisupport.c optional pci
+pci_if.o optional pci \
+ dependency "pci_if.c pci_if.h" \
+ compile-with "${NORMAL_C}" \
+ no-implicit-rule local
+pci_if.c optional pci \
+ dependency "$S/kern/makedevops.pl $S/pci/pci_if.m" \
+ compile-with "perl5 $S/kern/makedevops.pl -c $S/pci/pci_if.m" \
+ no-obj no-implicit-rule before-depend local \
+ clean "pci_if.c"
+pci_if.h optional pci \
+ dependency "$S/kern/makedevops.pl $S/pci/pci_if.m" \
+ compile-with "perl5 $S/kern/makedevops.pl -h $S/pci/pci_if.m" \
+ no-obj no-implicit-rule before-depend \
+ clean "pci_if.h"
+pci/tek390.c optional amd device-driver
pci/simos.c optional simos device-driver
pci/alpm.c optional alpm device-driver
pci/xrpu.c optional xrpu device-driver
diff --git a/sys/conf/files.alpha b/sys/conf/files.alpha
index 6f747e3..d0f4003 100644
--- a/sys/conf/files.alpha
+++ b/sys/conf/files.alpha
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.alpha,v 1.16 1999/01/23 16:53:26 dfr Exp $
+# $Id: files.alpha,v 1.17 1999/03/10 10:36:50 yokota Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -112,10 +112,13 @@ mcclock_if.h standard \
no-obj no-implicit-rule before-depend \
clean "mcclock_if.h"
alpha/pci/cia.c optional cia
+alpha/pci/cia_pci.c optional cia
alpha/pci/pci_eb164_intr.s optional cia
alpha/pci/apecs.c optional apecs
+alpha/pci/apecs_pci.c optional apecs
alpha/pci/pci_eb64plus_intr.s optional apecs
alpha/pci/lca.c optional lca
+alpha/pci/lca_pci.c optional lca
alpha/pci/pcibus.c optional pci
alpha/isa/isa.c optional isa
alpha/isa/mcclock_isa.c optional isa
@@ -157,3 +160,10 @@ dev/syscons/syscons.c optional sc device-driver
dev/syscons/scvidctl.c optional sc device-driver
isa/syscons_isa.c optional sc device-driver
isa/psm.c optional psm device-driver
+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
+dev/ata/ata-disk.c optional atadisk device-driver
+dev/ata/atapi-cd.c optional atapicd device-driver
+dev/ata/atapi-fd.c optional atapifd device-driver
+dev/ata/atapi-tape.c optional atapist device-driver
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 81f360e..ba0dba1 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.234 1999/04/13 19:38:10 peter Exp $
+# $Id: files.i386,v 1.235 1999/04/15 14:52:23 bde Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -90,6 +90,7 @@ 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
@@ -125,8 +126,8 @@ i386/ibcs2/imgact_coff.c optional ibcs2
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/atkbd_isa.c optional atkbd device-driver
-i386/isa/atkbdc_isa.c optional atkbdc device-driver
+isa/atkbd_isa.c optional atkbd device-driver
+isa/atkbdc_isa.c optional atkbdc device-driver
i386/isa/bt_isa.c optional bt device-driver
i386/isa/clock.c standard
i386/isa/cronyx.c optional cx device-driver
@@ -177,6 +178,8 @@ i386/isa/mse.c optional mse device-driver
i386/isa/npx.c mandatory npx device-driver
i386/isa/pcaudio.c optional pca device-driver
i386/isa/matcd/matcd.c optional matcd device-driver
+i386/isa/isa_compat.c optional isa device-driver
+i386/isa/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
@@ -190,7 +193,7 @@ 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
@@ -198,7 +201,7 @@ i386/isa/scd.c optional scd device-driver
i386/isa/si.c optional si device-driver
i386/isa/si2_z280.c optional si device-driver
i386/isa/si3_t225.c optional si device-driver
-i386/isa/sio.c optional sio device-driver
+isa/sio.c optional sio device-driver
i386/isa/snd/sound.c optional pcm device-driver
i386/isa/snd/dmabuf.c optional pcm device-driver
i386/isa/snd/ad1848.c optional pcm device-driver
@@ -268,9 +271,9 @@ i386/isa/sound/cs4232.c optional css device-driver
i386/isa/spigot.c optional spigot device-driver
i386/isa/spkr.c optional speaker device-driver
i386/isa/stallion.c optional stl device-driver
-i386/isa/syscons_isa.c optional sc device-driver
+isa/syscons_isa.c optional sc device-driver
i386/isa/vesa.c optional vga device-driver
-i386/isa/vga_isa.c optional vga device-driver
+isa/vga_isa.c optional vga device-driver
i386/isa/tw.c optional tw device-driver
i386/isa/wd.c optional wdc device-driver
i386/isa/wd.c optional wd device-driver
diff --git a/sys/dev/aha/aha_isa.c b/sys/dev/aha/aha_isa.c
index 9426679..c3704df 100644
--- a/sys/dev/aha/aha_isa.c
+++ b/sys/dev/aha/aha_isa.c
@@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aha_isa.c,v 1.5 1998/11/10 06:44:54 gibbs Exp $
+ * $Id: aha_isa.c,v 1.6 1999/01/20 06:21:23 imp Exp $
*/
#include "pnp.h"
@@ -257,7 +257,6 @@ static void
ahapnp_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 >= NAHATOT)
return;
@@ -278,9 +277,7 @@ ahapnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
if (dev->id_driver == NULL) {
dev->id_driver = &ahadriver;
- dvp = find_isadev(isa_devtab_tty, &ahadriver, 0);
- if (dvp != NULL)
- dev->id_id = dvp->id_id;
+ dev->id_id = isa_compat_nextid();
}
if ((dev->id_alive = aha_isa_probe(dev)) != 0)
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 680c334..4bee8d3 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.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: ata-all.c,v 1.5 1999/03/28 18:57:18 sos Exp $
+ * $Id: ata-all.c,v 1.6 1999/04/10 18:53:35 sos Exp $
*/
#include "ata.h"
@@ -44,12 +44,18 @@
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/clock.h>
+#ifdef __i386__
#include <machine/smp.h>
+#endif
#include <pci/pcivar.h>
#include <pci/pcireg.h>
+#ifdef __i386__
#include <i386/isa/icu.h>
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
+#else
+#include <isa/isareg.h>
+#endif
#include <dev/ata/ata-all.h>
#include <dev/ata/ata-disk.h>
#include <dev/ata/atapi-all.h>
@@ -62,7 +68,7 @@
#endif
/* prototypes */
-#if NISA > 0
+#if NISA > 0 && defined(__i386__)
static int32_t ata_isaprobe(struct isa_device *);
static int32_t ata_isaattach(struct isa_device *);
#endif
@@ -76,9 +82,10 @@ static void ataintr(int32_t);
static int32_t atanlun = 0;
struct ata_softc *atadevices[MAXATA];
+
+#if NISA > 0 && defined(__i386__)
struct isa_driver atadriver = { ata_isaprobe, ata_isaattach, "ata" };
-#if NISA > 0
static int32_t
ata_isaprobe(struct isa_device *devp)
{
@@ -133,6 +140,10 @@ ata_pciprobe(pcici_t tag, pcidi_t type)
return "Promise Ultra/33 IDE controller";
case 0x522910b9:
return "AcerLabs Aladdin IDE controller";
+ case 0x06401095:
+ return "CMD 640 IDE controller";
+ case 0x06461095:
+ return "CMD 646 IDE controller";
#if 0
case 0x05711106:
return "VIA Apollo IDE controller";
@@ -222,14 +233,18 @@ ata_pciattach(pcici_t tag, int32_t unit)
lun = 0;
if (ata_probe(iobase_1, altiobase_1, bmaddr_1, tag, &lun)) {
if (iobase_1 == IO_WD1)
+#ifdef __i386__
register_intr(irq1, (int)"", 0, (inthand2_t *)ataintr,
&bio_imask, lun);
+#else
+ alpha_platform_setup_ide_intr(0, ataintr, (void *)(intptr_t)lun);
+#endif
else {
if (sysctrl)
pci_map_int(tag, (inthand2_t *)promise_intr,
- (void *)lun, &bio_imask);
+ (void *)(intptr_t)lun, &bio_imask);
else
- pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
+ pci_map_int(tag, (inthand2_t *)ataintr, (void *)(intptr_t)lun,&bio_imask);
}
printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
lun, iobase_1, isa_apic_irq(irq1), unit);
@@ -237,11 +252,15 @@ ata_pciattach(pcici_t tag, int32_t unit)
lun = 1;
if (ata_probe(iobase_2, altiobase_2, bmaddr_2, tag, &lun)) {
if (iobase_2 == IO_WD2)
+#ifdef __i386__
register_intr(irq2, (int)"", 0, (inthand2_t *)ataintr,
&bio_imask, lun);
+#else
+ alpha_platform_setup_ide_intr(1, ataintr, (void *)(intptr_t)lun);
+#endif
else {
if (!sysctrl)
- pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask);
+ pci_map_int(tag, (inthand2_t *)ataintr, (void *)(intptr_t)lun,&bio_imask);
}
printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
lun, iobase_2, isa_apic_irq(irq2), unit);
@@ -418,6 +437,7 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr,
#ifndef ATA_STATIC_ID
atanlun++;
#endif
+ outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
return ATA_IOSIZE;
}
@@ -571,7 +591,7 @@ printf("ata_command: addr=%04x, device=%02x, cmd=%02x, c=%d, h=%d, s=%d, count=%
scp->active = ATA_WAIT_INTR;
outb(scp->ioaddr + ATA_CMD, command);
if (tsleep((caddr_t)scp, PRIBIO, "atacmd", 500)) {
- printf("ata_command: timeout waiting for interrupt");
+ printf("ata_command: timeout waiting for interrupt\n");
scp->active = ATA_IDLE;
return -1;
}
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index c5f7a41..c5efe55 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.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: ata-disk.c,v 1.5 1999/03/28 18:57:18 sos Exp $
+ * $Id: ata-disk.c,v 1.6 1999/04/10 18:53:35 sos Exp $
*/
#include "ata.h"
@@ -527,11 +527,11 @@ ad_transfer(struct buf *bp)
/* output the data */
#if 0
outsw(adp->controller->ioaddr + ATA_DATA,
- (void *)((int32_t)bp->b_data + adp->donecount),
+ (void *)((uintptr_t)bp->b_data + adp->donecount),
adp->currentsize / sizeof(int16_t));
#else
outsl(adp->controller->ioaddr + ATA_DATA,
- (void *)((int32_t)bp->b_data + adp->donecount),
+ (void *)((uintptr_t)bp->b_data + adp->donecount),
adp->currentsize / sizeof(int32_t));
#endif
adp->bytecount -= adp->currentsize;
@@ -590,11 +590,11 @@ oops:
/* data ready, read in */
#if 0
insw(adp->controller->ioaddr + ATA_DATA,
- (void *)((int32_t)bp->b_data + adp->donecount),
+ (void *)((uintptr_t)bp->b_data + adp->donecount),
adp->currentsize / sizeof(int16_t));
#else
insl(adp->controller->ioaddr + ATA_DATA,
- (void *)((int32_t)bp->b_data + adp->donecount),
+ (void *)((uintptr_t)bp->b_data + adp->donecount),
adp->currentsize / sizeof(int32_t));
#endif
adp->bytecount -= adp->currentsize;
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index fe0a08c..0886dbe 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.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: ata-dma.c,v 1.3 1999/03/30 13:09:47 sos Exp $
+ * $Id: ata-dma.c,v 1.4 1999/04/10 18:53:35 sos Exp $
*/
#include "ata.h"
@@ -42,6 +42,12 @@
#include <pci/pcireg.h>
#include <dev/ata/ata-all.h>
+#ifdef __alpha__
+#undef vtophys
+#define vtophys(va) (pmap_kextract(((vm_offset_t) (va))) \
+ + 1*1024*1024*1024)
+#endif
+
/* misc defines */
#define MIN(a,b) ((a)>(b)?(b):(a))
@@ -64,7 +70,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!(dmatab = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT)))
return -1;
- if (((int)dmatab>>PAGE_SHIFT)^(((int)dmatab+PAGE_SIZE-1)>>PAGE_SHIFT)) {
+ if (((uintptr_t)dmatab>>PAGE_SHIFT)^(((uintptr_t)dmatab+PAGE_SIZE-1)>>PAGE_SHIFT)) {
printf("ata_dmainit: dmatab crosses page boundary, no DMA\n");
free(dmatab, M_DEVBUF);
return -1;
@@ -252,7 +258,7 @@ ata_dmasetup(struct ata_softc *scp, int32_t device,
#ifdef ATA_DEBUGDMA
printf("ata%d: dmasetup\n", scp->lun);
#endif
- if (((u_int32_t)data & 1) || (count & 1))
+ if (((uintptr_t)data & 1) || (count & 1))
return -1;
if (!count) {
@@ -263,7 +269,7 @@ ata_dmasetup(struct ata_softc *scp, int32_t device,
dmatab = scp->dmatab[device ? 1 : 0];
dma_base = vtophys(data);
- dma_count = MIN(count, (PAGE_SIZE - ((u_int32_t)data & PAGE_MASK)));
+ dma_count = MIN(count, (PAGE_SIZE - ((uintptr_t)data & PAGE_MASK)));
data += dma_count;
count -= dma_count;
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index 6322475..3b48966 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.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: atapi-all.c,v 1.5 1999/03/28 18:57:19 sos Exp $
+ * $Id: atapi-all.c,v 1.6 1999/04/10 18:53:35 sos Exp $
*/
#include "ata.h"
@@ -310,13 +310,13 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
printf("atapi_interrupt: write data underrun %d/%d\n",
length, request->bytecount);
outsw(atp->controller->ioaddr + ATA_DATA,
- (void *)((int32_t)request->data), length / sizeof(int16_t));
+ (void *)((uintptr_t)request->data), length / sizeof(int16_t));
for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
outw(atp->controller->ioaddr + ATA_DATA, 0);
}
else {
outsw(atp->controller->ioaddr + ATA_DATA,
- (void *)((int32_t)request->data), length / sizeof(int16_t));
+ (void *)((uintptr_t)request->data), length / sizeof(int16_t));
}
request->bytecount -= length;
request->data += length;
@@ -331,13 +331,13 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
printf("atapi_interrupt: read data overrun %d/%d\n",
length, request->bytecount);
insw(atp->controller->ioaddr + ATA_DATA,
- (void *)((int32_t)request->data), length / sizeof(int16_t));
+ (void *)((uintptr_t)request->data), length / sizeof(int16_t));
for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
inw(atp->controller->ioaddr + ATA_DATA);
}
else {
insw(atp->controller->ioaddr + ATA_DATA,
- (void *)((int32_t)request->data), length / sizeof(int16_t));
+ (void *)((uintptr_t)request->data), length / sizeof(int16_t));
}
request->bytecount -= length;
request->data += length;
diff --git a/sys/dev/atkbdc/atkbd.c b/sys/dev/atkbdc/atkbd.c
index f9e28fe..80c81a5 100644
--- a/sys/dev/atkbdc/atkbd.c
+++ b/sys/dev/atkbdc/atkbd.c
@@ -23,7 +23,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: atkbd.c,v 1.4 1999/01/28 10:55:55 yokota Exp $
+ * $Id: atkbd.c,v 1.5 1999/03/10 10:36:52 yokota Exp $
*/
#include "atkbd.h"
@@ -46,7 +46,7 @@
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
-#ifndef __i386__
+#if 1
#include <sys/bus.h>
#include <isa/isareg.h>
@@ -89,6 +89,7 @@ static struct cdevsw atkbd_cdevsw = {
#endif /* KBD_INSTALL_CDEV */
+#if 0
#ifdef __i386__
atkbd_softc_t
@@ -110,6 +111,7 @@ atkbd_softc_t
}
#endif /* __i386__ */
+#endif
int
atkbd_probe_unit(int unit, int port, int irq, int flags)
@@ -376,16 +378,14 @@ atkbd_configure(int flags)
{
keyboard_t *kbd;
int arg[2];
-#ifdef __i386__
- struct isa_device *dev;
int i;
/* XXX: a kludge to obtain the device configuration flags */
- dev = find_isadev(isa_devtab_tty, &atkbddriver, 0);
- if (dev != NULL) {
- flags |= dev->id_flags;
+ if (resource_int_value("atkbd", 0, "flags", &i) == 0) {
+ flags |= i;
/* if the driver is disabled, unregister the keyboard if any */
- if (!dev->id_enabled) {
+ if (resource_int_value("atkbd", 0, "disabled", &i) == 0
+ && i != 0) {
i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT);
if (i >= 0) {
kbd = kbd_get_keyboard(i);
@@ -395,8 +395,7 @@ atkbd_configure(int flags)
}
}
}
-#endif
-
+
/* probe the keyboard controller */
atkbdc_configure();
diff --git a/sys/dev/atkbdc/atkbd_atkbdc.c b/sys/dev/atkbdc/atkbd_atkbdc.c
index ade1ba0..1d7ee62 100644
--- a/sys/dev/atkbdc/atkbd_atkbdc.c
+++ b/sys/dev/atkbdc/atkbd_atkbdc.c
@@ -23,7 +23,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: atkbd_isa.c,v 1.1 1999/01/23 16:53:27 dfr Exp $
+ * $Id: atkbd_isa.c,v 1.2 1999/03/10 10:36:49 yokota Exp $
*/
#include "atkbd.h"
@@ -37,6 +37,7 @@
#include <sys/conf.h>
#include <sys/tty.h>
#include <sys/bus.h>
+#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
@@ -70,9 +71,9 @@ static driver_t atkbd_driver = {
static int
atkbdprobe(device_t dev)
{
- u_long port;
- u_long irq;
- u_long flags;
+ uintptr_t port;
+ uintptr_t irq;
+ uintptr_t flags;
device_set_desc(dev, "AT Keyboard");
@@ -89,9 +90,9 @@ static int
atkbdattach(device_t dev)
{
atkbd_softc_t *sc;
- u_long port;
- u_long irq;
- u_long flags;
+ uintptr_t port;
+ uintptr_t irq;
+ uintptr_t flags;
struct resource *res;
void *ih;
int zero = 0;
diff --git a/sys/dev/atkbdc/atkbd_isa.c b/sys/dev/atkbdc/atkbd_isa.c
index ade1ba0..1d7ee62 100644
--- a/sys/dev/atkbdc/atkbd_isa.c
+++ b/sys/dev/atkbdc/atkbd_isa.c
@@ -23,7 +23,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: atkbd_isa.c,v 1.1 1999/01/23 16:53:27 dfr Exp $
+ * $Id: atkbd_isa.c,v 1.2 1999/03/10 10:36:49 yokota Exp $
*/
#include "atkbd.h"
@@ -37,6 +37,7 @@
#include <sys/conf.h>
#include <sys/tty.h>
#include <sys/bus.h>
+#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
@@ -70,9 +71,9 @@ static driver_t atkbd_driver = {
static int
atkbdprobe(device_t dev)
{
- u_long port;
- u_long irq;
- u_long flags;
+ uintptr_t port;
+ uintptr_t irq;
+ uintptr_t flags;
device_set_desc(dev, "AT Keyboard");
@@ -89,9 +90,9 @@ static int
atkbdattach(device_t dev)
{
atkbd_softc_t *sc;
- u_long port;
- u_long irq;
- u_long flags;
+ uintptr_t port;
+ uintptr_t irq;
+ uintptr_t flags;
struct resource *res;
void *ih;
int zero = 0;
diff --git a/sys/dev/atkbdc/psm.c b/sys/dev/atkbdc/psm.c
index e7eb469..b3dc1d0 100644
--- a/sys/dev/atkbdc/psm.c
+++ b/sys/dev/atkbdc/psm.c
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: psm.c,v 1.2 1998/11/15 18:25:17 dfr Exp $
+ * $Id: psm.c,v 1.3 1999/01/23 16:53:28 dfr Exp $
*/
/*
@@ -76,6 +76,7 @@
#include <sys/poll.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
+#include <machine/bus.h>
#include <sys/rman.h>
#ifdef DEVFS
#include <sys/devfsext.h>
@@ -740,8 +741,8 @@ psmprobe(device_t dev)
{
int unit = device_get_unit(dev);
struct psm_softc *sc = device_get_softc(dev);
- u_long port;
- u_long flags;
+ uintptr_t port;
+ uintptr_t flags;
int stat[3];
int command_byte;
int mask;
@@ -991,7 +992,7 @@ psmattach(device_t dev)
struct psm_softc *sc = device_get_softc(dev);
void *ih;
struct resource *res;
- u_long irq;
+ uintptr_t irq;
int zero = 0;
if (sc == NULL) /* shouldn't happen */
diff --git a/sys/dev/cs/if_cs.c b/sys/dev/cs/if_cs.c
index 4a9c390..f96f024 100644
--- a/sys/dev/cs/if_cs.c
+++ b/sys/dev/cs/if_cs.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: if_cs.c,v 1.8 1999/01/12 00:27:43 eivind Exp $
+ * $Id: if_cs.c,v 1.9 1999/01/28 01:59:53 dillon Exp $
*
* Device driver for Crystal Semiconductor CS8920 based ethernet
* adapters. By Maxim Bolotin and Oleg Sharoiko, 27-April-1997
@@ -1352,7 +1352,6 @@ cs_pnp_attach(u_long csn, u_long vend_id, char *name,
int iobase, unit, flags;
u_int irq;
int drq;
- struct isa_device *dvp;
struct cs_softc *sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT);
if (read_pnp_parms ( &d , ldn ) == 0 ) {
@@ -1373,9 +1372,7 @@ cs_pnp_attach(u_long csn, u_long vend_id, char *name,
if (dev->id_driver == NULL) {
dev->id_driver = &csdriver;
- dvp = find_isadev(isa_devtab_net, &csdriver, 0);
- if (dvp != NULL)
- dev->id_id = dvp->id_id;
+ dev->id_id = isa_compat_nextid();
}
if (!sc) return;
diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c
index 1408b2b..29bb9d1 100644
--- a/sys/dev/ed/if_ed.c
+++ b/sys/dev/ed/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.149 1999/01/28 01:59:53 dillon Exp $
+ * $Id: if_ed.c,v 1.150 1999/03/17 16:44:51 luigi Exp $
*/
/*
@@ -3488,7 +3488,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;
@@ -3509,9 +3508,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/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 07223f1..0414b18 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -47,7 +47,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.133 1999/02/10 00:03:32 ken Exp $
+ * $Id: fd.c,v 1.134 1999/04/06 03:06:51 peter Exp $
*
*/
@@ -60,26 +60,37 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <machine/clock.h>
-#include <machine/ioctl_fd.h>
#include <sys/disklabel.h>
-#include <sys/buf.h>
#include <sys/devicestat.h>
+#include <sys/fcntl.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/proc.h>
#include <sys/syslog.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/fdreg.h>
-#include <i386/isa/fdc.h>
-#include <i386/isa/rtc.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/clock.h>
+#include <machine/ioctl_fd.h>
+#include <machine/resource.h>
#include <machine/stdarg.h>
+
#ifdef DEVFS
#include <sys/devfsext.h>
#endif /* DEVFS */
+#include <isa/isavar.h>
+#include <i386/isa/isa.h>
+#include <i386/isa/isa_dma.h>
+#include <i386/isa/fdreg.h>
+#include <i386/isa/fdc.h>
+#include <i386/isa/rtc.h>
+
/* misuse a flag to identify format operation */
#define B_FORMAT B_XXX
@@ -151,13 +162,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...) */
@@ -179,7 +190,10 @@ static struct fd_data {
void *bdevs[1 + NUMDENS + MAXPARTITIONS];
void *cdevs[1 + NUMDENS + MAXPARTITIONS];
#endif
-} fd_data[NFD];
+ device_t dev;
+ fdu_t fdu;
+};
+static devclass_t fd_devclass;
/***********************************************************************\
* Throughout this file the following conventions will be used: *
@@ -195,29 +209,26 @@ static struct fd_data {
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);
@@ -356,13 +367,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;
@@ -374,28 +378,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;
@@ -407,9 +401,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;
@@ -422,26 +415,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);
}
}
@@ -462,8 +455,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;
@@ -474,17 +467,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;
}
@@ -493,9 +486,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;
@@ -506,13 +499,11 @@ 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;
- 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;
}
@@ -520,17 +511,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)
@@ -545,8 +534,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
@@ -554,7 +542,7 @@ fd_read_status(fdc_p fdc, int fdsu)
*/
int status;
- ret = fd_in(fdc->fdcu, &status);
+ ret = fd_in(fdc, &status);
fdc->status[i] = status;
if (ret != 0)
break;
@@ -572,34 +560,92 @@ fd_read_status(fdc_p fdc, int fdsu)
/* autoconfiguration stuff */
/****************************************************************************/
-/*
- * 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);
/* 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);
/* see if it can handle a command */
- if (fd_cmd(fdcu,
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
- 0))
- {
- return(0);
+ if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
+ NE7_SPEC_2(2, 0), 0)) {
+ error = ENXIO;
+ goto out;
+ }
+
+ 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;
+ }
}
+
+ 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
@@ -608,277 +654,312 @@ 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;
- int fdsu, st0, st3, i;
- struct isa_device *fdup;
- int ic_type = 0;
-#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;
- fdc->dmachan = dev->id_drq;
+
/* 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;
+
/* reset controller, turn motor off, clear fdout mirror reg */
outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
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) {
- 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;
- }
- /* is there a unit? */
- if ((fdt == RTCFDT_NONE)
- ) {
- fd->type = NO_TYPE;
- continue;
- }
+#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));
+}
- /* select it */
- set_motor(fdcu, fdsu, TURNON);
- DELAY(1000000); /* 1 sec */
+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));
+}
- 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");
+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
- fdc->fdct = FDC_NE72065;
- break;
- default:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("unknown IC type %02x\n", ic_type);
+
+ 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);
+
+ /* 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;
+ }
+
+ /* is there a unit? */
+ if (fdt == RTCFDT_NONE)
+ return (ENXIO);
+
+ /* 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);
- 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) {
- case RTCFDT_12M:
- printf("1.2MB 5.25in\n");
- fd->type = FD_1200;
- 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;
+ fd->track = FD_NO_TRACK;
+ fd->fdc = fdc;
+ fd->fdsu = fdsu;
+ fd->options = 0;
+ callout_handle_init(&fd->toffhandle);
+ callout_handle_init(&fd->tohandle);
+
+ 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);
+ }
+ return (0);
+}
+
+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.
+ */
+ switch (fd->type) {
+ case FD_360:
+ if (i != FD_360)
+ continue;
break;
- case RTCFDT_288M:
- case RTCFDT_288M_1:
- printf("2.88MB 3.5in - 1.44MB mode\n");
- fd->type = FD_1440;
+ case FD_720:
+ if (i != FD_720 && i != FD_800 && i != FD_820)
+ continue;
break;
- case RTCFDT_360K:
- printf("360KB 5.25in\n");
- fd->type = FD_360;
+ 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_720K:
- printf("720KB 3.5in\n");
- fd->type = FD_720;
+ 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;
- 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.
- */
- 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;
- }
- 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;
- 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 */
+ 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;
+ 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
@@ -1016,9 +1097,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;
if(turnon) {
@@ -1038,83 +1119,78 @@ set_motor(fdcu_t fdcu, int fdsu, int turnon)
fdout |= (FDO_FRST|FDO_FDMAEN);
}
- outb(fdc_data[fdcu].baseport+FDOUT, fdout);
- 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
* from its sleep, we silently assume the command will
* be accepted, and do not test for a timeout
*/
- (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);
- 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 */
outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
@@ -1127,7 +1203,7 @@ fdc_reset(fdc_p fdc)
TRACE1("[0x%x->FDOUT]", fdc->fdout);
/* XXX after a reset, silently believe the FDC will accept commands */
- (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);
if (fdc->flags & FDC_HAS_FIFO)
@@ -1138,16 +1214,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);
@@ -1161,16 +1237,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);
@@ -1185,21 +1261,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);
@@ -1215,32 +1291,33 @@ 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);
if (type == 0)
- type = fd_data[fdu].type;
+ type = fd->type;
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) {
@@ -1279,9 +1356,10 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
}
}
}
- 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;
}
@@ -1289,11 +1367,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
@@ -1317,16 +1397,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;
@@ -1341,7 +1422,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);
@@ -1386,12 +1467,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;
@@ -1409,27 +1490,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);
/*
@@ -1447,19 +1526,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);
}
@@ -1469,11 +1547,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
@@ -1513,7 +1591,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;
@@ -1537,26 +1615,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;
@@ -1569,8 +1646,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:
@@ -1585,10 +1662,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 *
@@ -1596,12 +1672,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);
}
if (fdc->flags & FDC_NEEDS_RESET) {
fdc->state = RESETCTLR;
@@ -1615,7 +1691,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdc->state = SEEKCOMPLETE;
break;
}
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK,
+ if (fd_cmd(fdc, 3, NE7CMD_SEEK,
fd->fdsu, b_cylinder * fd->ft->steptrac,
0))
{
@@ -1624,20 +1700,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 {
/*
@@ -1669,8 +1744,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
@@ -1685,22 +1759,20 @@ 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));
}
}
- 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));
}
}
@@ -1726,7 +1798,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)
{
@@ -1749,8 +1821,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,
@@ -1758,25 +1829,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) {
/*
@@ -1795,7 +1860,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 */
@@ -1805,14 +1870,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
@@ -1834,8 +1898,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 FDC_YE
case PIOREAD:
/*
@@ -1847,16 +1911,15 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
/* FALLTHROUGH */
#endif
case IOCOMPLETE: /* IO DONE, post-analyze */
- untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle);
+ untimeout(fd_iotimeout, fdc, fd->tohandle);
- 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;
@@ -1869,8 +1932,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
#endif
isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
format ? bp->b_bcount : fdblk, fdc->dmachan);
- 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) {
/*
@@ -1890,17 +1952,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;
@@ -1915,7 +1974,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++;
@@ -1931,21 +1990,18 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdc->state = STARTRECAL;
/* Fall through. */
case STARTRECAL:
- 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 {
/*
@@ -1971,16 +2027,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;
@@ -1993,9 +2049,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],
@@ -2010,28 +2067,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;
@@ -2084,10 +2144,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
@@ -2104,7 +2164,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() */
@@ -2135,20 +2195,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
@@ -2171,7 +2230,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;
@@ -2181,13 +2240,12 @@ fdioctl(dev, cmd, addr, flag, p)
fdblk = 128 << fd->ft->secsize;
- 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;
@@ -2211,8 +2269,7 @@ fdioctl(dev, cmd, addr, flag, p)
break;
case DIOCWDINFO:
- if ((flag & FWRITE) == 0)
- {
+ if ((flag & FWRITE) == 0) {
error = EBADF;
break;
}
@@ -2227,9 +2284,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
@@ -2242,7 +2299,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;
@@ -2262,22 +2319,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/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 77f0ade..53b8d4d 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_fxp.c,v 1.65 1999/03/17 16:44:53 luigi Exp $
+ * $Id: if_fxp.c,v 1.66 1999/03/20 04:51:25 wes Exp $
*/
/*
@@ -89,6 +89,10 @@
#else /* __FreeBSD__ */
#include <sys/sockio.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
@@ -491,51 +495,31 @@ fxp_ether_ioctl(ifp, cmd, data)
#else /* __FreeBSD__ */
-static u_long fxp_count;
-static const char *fxp_probe __P((pcici_t, pcidi_t));
-static void fxp_attach __P((pcici_t, int));
-
-static void fxp_shutdown __P((int, void *));
-
-static struct pci_device fxp_device = {
- "fxp",
- fxp_probe,
- fxp_attach,
- &fxp_count,
- NULL
-};
-DATA_SET(pcidevice_set, fxp_device);
-
/*
* Return identification string if this is device is ours.
*/
-static const char *
-fxp_probe(config_id, device_id)
- pcici_t config_id;
- pcidi_t device_id;
+static int
+fxp_probe(device_t dev)
{
- if (((device_id & 0xffff) == FXP_VENDORID_INTEL) &&
- ((device_id >> 16) & 0xffff) == FXP_DEVICEID_i82557)
- return ("Intel EtherExpress Pro 10/100B Ethernet");
+ if ((pci_get_vendor(dev) == FXP_VENDORID_INTEL) &&
+ (pci_get_device(dev) == FXP_DEVICEID_i82557)) {
+ device_set_desc(dev, "Intel EtherExpress Pro 10/100B Ethernet");
+ return 0;
+ }
- return NULL;
+ return ENXIO;
}
-static void
-fxp_attach(config_id, unit)
- pcici_t config_id;
- int unit;
+static int
+fxp_attach(device_t dev)
{
- struct fxp_softc *sc;
- vm_offset_t pbase;
+ int error = 0;
+ struct fxp_softc *sc = device_get_softc(dev);
struct ifnet *ifp;
int s;
u_long val;
+ int rid;
- sc = malloc(sizeof(struct fxp_softc), M_DEVBUF, M_NOWAIT);
- if (sc == NULL)
- return;
- bzero(sc, sizeof(struct fxp_softc));
callout_handle_init(&sc->stat_ch);
s = splimp();
@@ -543,39 +527,56 @@ fxp_attach(config_id, unit)
/*
* Enable bus mastering.
*/
- val = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
+ val = pci_read_config(dev, PCIR_COMMAND, 2);
val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
- pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, val);
+ pci_write_config(dev, PCIR_COMMAND, val, 2);
/*
* Map control/status registers.
*/
- if (!pci_map_mem(config_id, FXP_PCI_MMBA,
- (vm_offset_t *)&sc->csr, &pbase)) {
- printf("fxp%d: couldn't map memory\n", unit);
+ rid = FXP_PCI_MMBA;
+ sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!sc->mem) {
+ device_printf(dev, "could not map memory\n");
+ error = ENXIO;
goto fail;
- }
+ }
+ sc->csr = rman_get_virtual(sc->mem); /* XXX use bus_space */
/*
* Allocate our interrupt.
*/
- if (!pci_map_int(config_id, fxp_intr, sc, &net_imask)) {
- printf("fxp%d: couldn't map interrupt\n", unit);
+ rid = 0;
+ sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (sc->irq == NULL) {
+ device_printf(dev, "could not map interrupt\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ error = bus_setup_intr(dev, sc->irq, fxp_intr, sc, &sc->ih);
+ if (error) {
+ device_printf(dev, "could not setup irq\n");
goto fail;
}
/* Do generic parts of attach. */
if (fxp_attach_common(sc, sc->arpcom.ac_enaddr)) {
/* Failed! */
- (void) pci_unmap_int(config_id);
+ bus_teardown_intr(dev, sc->irq, sc->ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, SYS_RES_MEMORY, FXP_PCI_MMBA, sc->mem);
+ error = ENXIO;
goto fail;
}
- printf("fxp%d: Ethernet address %6D%s\n", unit,
+ device_printf(dev, "Ethernet address %6D%s\n",
sc->arpcom.ac_enaddr, ":", sc->phy_10Mbps_only ? ", 10Mbps" : "");
ifp = &sc->arpcom.ac_if;
- ifp->if_unit = unit;
+ ifp->if_unit = device_get_unit(dev);
ifp->if_name = "fxp";
ifp->if_output = ether_output;
ifp->if_baudrate = 100000000;
@@ -600,19 +601,63 @@ fxp_attach(config_id, unit)
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
#endif
+ splx(s);
+ return 0;
+
+ fail:
+ splx(s);
+ return error;
+}
+
+/*
+ * Detach interface.
+ */
+static int
+fxp_detach(device_t dev)
+{
+ struct fxp_softc *sc = device_get_softc(dev);
+ int s;
+
+ s = splimp();
+
/*
- * Add shutdown hook so that DMA is disabled prior to reboot. Not
- * doing do could allow DMA to corrupt kernel memory during the
- * reboot before the driver initializes.
+ * Close down routes etc.
*/
- at_shutdown(fxp_shutdown, sc, SHUTDOWN_POST_SYNC);
+ if_detach(&sc->arpcom.ac_if);
- splx(s);
- return;
+ /*
+ * Stop DMA and drop transmit queue.
+ */
+ fxp_stop(sc);
+
+ /*
+ * Deallocate resources.
+ */
+ bus_teardown_intr(dev, sc->irq, sc->ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, SYS_RES_MEMORY, FXP_PCI_MMBA, sc->mem);
+
+ /*
+ * Free all the receive buffers.
+ */
+ if (sc->rfa_headm != NULL)
+ m_freem(sc->rfa_headm);
+
+ /*
+ * Free all media structures.
+ */
+ ifmedia_removeall(&sc->sc_media);
+
+ /*
+ * Free anciliary structures.
+ */
+ free(sc->cbl_base, M_DEVBUF);
+ free(sc->fxp_stats, M_DEVBUF);
+ free(sc->mcsp, M_DEVBUF);
- fail:
- free(sc, M_DEVBUF);
splx(s);
+
+ return 0;
}
/*
@@ -620,14 +665,39 @@ fxp_attach(config_id, unit)
* main purpose of this routine is to shut off receiver DMA so that
* kernel memory doesn't get clobbered during warmboot.
*/
-static void
-fxp_shutdown(howto, sc)
- int howto;
- void *sc;
+static int
+fxp_shutdown(device_t dev)
{
- fxp_stop((struct fxp_softc *) sc);
+ /*
+ * Make sure that DMA is disabled prior to reboot. Not doing
+ * do could allow DMA to corrupt kernel memory during the
+ * reboot before the driver initializes.
+ */
+ fxp_stop((struct fxp_softc *) device_get_softc(dev));
+ return 0;
}
+static device_method_t fxp_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, fxp_probe),
+ DEVMETHOD(device_attach, fxp_attach),
+ DEVMETHOD(device_detach, fxp_detach),
+ DEVMETHOD(device_shutdown, fxp_shutdown),
+
+ { 0, 0 }
+};
+
+static driver_t fxp_driver = {
+ "fxp",
+ fxp_methods,
+ DRIVER_TYPE_NET,
+ sizeof(struct fxp_softc),
+};
+
+static devclass_t fxp_devclass;
+
+DRIVER_MODULE(fxp, pci, fxp_driver, fxp_devclass, 0, 0);
+
#endif /* __NetBSD__ */
/*************************************************************
diff --git a/sys/dev/fxp/if_fxpvar.h b/sys/dev/fxp/if_fxpvar.h
index ce8d8fe..042d2df 100644
--- a/sys/dev/fxp/if_fxpvar.h
+++ b/sys/dev/fxp/if_fxpvar.h
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_fxpvar.h,v 1.5 1998/06/07 17:12:38 dfr Exp $
+ * $Id: if_fxpvar.h,v 1.6 1998/08/02 00:29:15 dg Exp $
*/
/*
@@ -48,6 +48,9 @@ struct fxp_softc {
#else
struct arpcom arpcom; /* per-interface network data */
caddr_t csr; /* control/status registers */
+ struct resource *mem; /* resource descriptor for registers */
+ struct resource *irq; /* resource descriptor for interrupt */
+ void *ih; /* interrupt handler cookie */
#endif /* __NetBSD__ */
struct mbuf *rfa_headm; /* first mbuf in receive frame area */
struct mbuf *rfa_tailm; /* last mbuf in receive frame area */
diff --git a/sys/dev/kbd/atkbd.c b/sys/dev/kbd/atkbd.c
index f9e28fe..80c81a5 100644
--- a/sys/dev/kbd/atkbd.c
+++ b/sys/dev/kbd/atkbd.c
@@ -23,7 +23,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: atkbd.c,v 1.4 1999/01/28 10:55:55 yokota Exp $
+ * $Id: atkbd.c,v 1.5 1999/03/10 10:36:52 yokota Exp $
*/
#include "atkbd.h"
@@ -46,7 +46,7 @@
#include <dev/kbd/atkbdreg.h>
#include <dev/kbd/atkbdcreg.h>
-#ifndef __i386__
+#if 1
#include <sys/bus.h>
#include <isa/isareg.h>
@@ -89,6 +89,7 @@ static struct cdevsw atkbd_cdevsw = {
#endif /* KBD_INSTALL_CDEV */
+#if 0
#ifdef __i386__
atkbd_softc_t
@@ -110,6 +111,7 @@ atkbd_softc_t
}
#endif /* __i386__ */
+#endif
int
atkbd_probe_unit(int unit, int port, int irq, int flags)
@@ -376,16 +378,14 @@ atkbd_configure(int flags)
{
keyboard_t *kbd;
int arg[2];
-#ifdef __i386__
- struct isa_device *dev;
int i;
/* XXX: a kludge to obtain the device configuration flags */
- dev = find_isadev(isa_devtab_tty, &atkbddriver, 0);
- if (dev != NULL) {
- flags |= dev->id_flags;
+ if (resource_int_value("atkbd", 0, "flags", &i) == 0) {
+ flags |= i;
/* if the driver is disabled, unregister the keyboard if any */
- if (!dev->id_enabled) {
+ if (resource_int_value("atkbd", 0, "disabled", &i) == 0
+ && i != 0) {
i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT);
if (i >= 0) {
kbd = kbd_get_keyboard(i);
@@ -395,8 +395,7 @@ atkbd_configure(int flags)
}
}
}
-#endif
-
+
/* probe the keyboard controller */
atkbdc_configure();
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index e449fc2..889550c 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -23,10 +23,12 @@
* (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: pci.c,v 1.93 1999/01/19 23:29:18 se Exp $
+ * $Id: pci.c,v 1.94 1999/04/11 02:47:31 eivind Exp $
*
*/
+#include "opt_bus.h"
+
#include "pci.h"
#if NPCI > 0
@@ -50,6 +52,11 @@
#include <vm/pmap.h>
#include <vm/vm_extern.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <pci/pci_ioctl.h>
@@ -338,11 +345,10 @@ pci_readcfg(pcicfgregs *probe)
M_DEVBUF, M_WAITOK);
if (devlist_entry == NULL)
return (NULL);
+ bzero(devlist_entry, sizeof *devlist_entry);
cfg = &devlist_entry->cfg;
- bzero(cfg, sizeof *cfg);
-
cfg->bus = probe->bus;
cfg->slot = probe->slot;
cfg->func = probe->func;
@@ -450,113 +456,6 @@ pci_freecfg(struct pci_devinfo *dinfo)
}
#endif
-static void
-pci_addcfg(struct pci_devinfo *dinfo)
-{
- if (bootverbose) {
- int i;
- pcicfgregs *cfg = &dinfo->cfg;
-
- printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
- cfg->vendor, cfg->device, cfg->revid);
- printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
- cfg->baseclass, cfg->subclass, cfg->progif,
- cfg->hdrtype, cfg->mfdev);
- printf("\tsubordinatebus=%x \tsecondarybus=%x\n",
- cfg->subordinatebus, cfg->secondarybus);
-#ifdef PCI_DEBUG
- printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
- cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
- printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
- cfg->lattimer, cfg->lattimer * 30,
- cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
-#endif /* PCI_DEBUG */
- if (cfg->intpin > 0)
- printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
-
- for (i = 0; i < cfg->nummaps; i++) {
- pcimap *m = &cfg->map[i];
- printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n",
- i, m->type, m->ln2range, m->base, m->ln2size);
- }
- }
- pci_drvattach(dinfo); /* XXX currently defined in pci_compat.c */
-}
-
-/* scan one PCI bus for devices */
-
-static int
-pci_probebus(int bus)
-{
- pcicfgregs probe;
- int bushigh = bus;
-
-#ifdef SIMOS
-#undef PCI_SLOTMAX
-#define PCI_SLOTMAX 0
-#endif
-
- bzero(&probe, sizeof probe);
- /* XXX KDM */
- /* probe.parent = pci_bridgeto(bus); */
- probe.bus = bus;
- for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) {
- int pcifunchigh = 0;
- for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) {
- struct pci_devinfo *dinfo = pci_readcfg(&probe);
- if (dinfo != NULL) {
- if (dinfo->cfg.mfdev)
- pcifunchigh = 7;
- /*
- * XXX: Temporarily move pci_addcfg() up before
- * the use of cfg->subordinatebus. This is
- * necessary, since pci_addcfg() calls the
- * device's probe(), which may read the bus#
- * from some device dependent register of
- * some host to PCI bridges. The probe will
- * eventually be moved to pci_readcfg(), and
- * pci_addcfg() will then be moved back down
- * below the conditional statement ...
- */
- pci_addcfg(dinfo);
-
- if (bushigh < dinfo->cfg.subordinatebus)
- bushigh = dinfo->cfg.subordinatebus;
- if (bushigh < dinfo->cfg.secondarybus)
- bushigh = dinfo->cfg.secondarybus;
-
- /* XXX KDM */
- /* cfg = NULL; we don't own this anymore ... */
- }
- }
- }
- return (bushigh);
-}
-
-/* scan a PCI bus tree reached through one PCI attachment point */
-
-int
-pci_probe(pciattach *parent)
-{
- int bushigh;
- int bus = 0;
-
- STAILQ_INIT(&pci_devq);
-
- bushigh = pci_bushigh();
- while (bus <= bushigh) {
- int newbushigh;
-
- printf("Probing for devices on PCI bus %d:\n", bus);
- newbushigh = pci_probebus(bus);
-
- if (bushigh < newbushigh)
- bushigh = newbushigh;
- bus++;
- }
- return (bushigh);
-}
-
/*
* This is the user interface to PCI configuration space.
*/
@@ -750,8 +649,8 @@ pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
"pci_match_conf) (%d)\npci_ioctl: "
"pat_buf_len should be = %d\n",
cio->pat_buf_len, cio->num_patterns,
- sizeof(struct pci_match_conf),
- sizeof(struct pci_match_conf) *
+ (int)sizeof(struct pci_match_conf),
+ (int)sizeof(struct pci_match_conf) *
cio->num_patterns);
printf("pci_ioctl: do your headers match your "
"kernel?\n");
@@ -945,4 +844,534 @@ pci_cdevinit(void *dummy)
SYSINIT(pcidev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+PCI_CDEV, pci_cdevinit, NULL);
+#include "pci_if.h"
+
+/*
+ * A simple driver to wrap the old pci driver mechanism for back-compat.
+ */
+
+static int
+pci_compat_probe(device_t dev)
+{
+ struct pci_device *dvp;
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+ const char *name;
+ int error;
+
+ dinfo = device_get_ivars(dev);
+ cfg = &dinfo->cfg;
+ dvp = device_get_driver(dev)->priv;
+
+ /*
+ * Do the wrapped probe.
+ */
+ error = ENXIO;
+ if (dvp && dvp->pd_probe) {
+ name = dvp->pd_probe(cfg, (cfg->device << 16) + cfg->vendor);
+ if (name) {
+ device_set_desc_copy(dev, name);
+ error = 0;
+ }
+ }
+
+ return error;
+}
+
+static int
+pci_compat_attach(device_t dev)
+{
+ struct pci_device *dvp;
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+ int unit;
+
+ dinfo = device_get_ivars(dev);
+ cfg = &dinfo->cfg;
+ dvp = device_get_driver(dev)->priv;
+
+ unit = device_get_unit(dev);
+ if (unit > *dvp->pd_count)
+ *dvp->pd_count = unit;
+ if (dvp->pd_attach)
+ dvp->pd_attach(cfg, unit);
+
+ /*
+ * XXX KDM for some devices, dvp->pd_name winds up NULL.
+ * I haven't investigated enough to figure out why this
+ * would happen.
+ */
+ if (dvp->pd_name != NULL)
+ strncpy(dinfo->conf.pd_name, dvp->pd_name,
+ sizeof(dinfo->conf.pd_name));
+ else
+ strncpy(dinfo->conf.pd_name, "????",
+ sizeof(dinfo->conf.pd_name));
+ dinfo->conf.pd_name[sizeof(dinfo->conf.pd_name) - 1] = 0;
+ dinfo->conf.pd_unit = unit;
+
+ return 0;
+}
+
+static device_method_t pci_compat_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pci_compat_probe),
+ DEVMETHOD(device_attach, pci_compat_attach),
+
+ { 0, 0 }
+};
+
+static devclass_t pci_devclass;
+
+/*
+ * Create a new style driver around each old pci driver.
+ */
+static void
+pci_wrap_old_drivers(void)
+{
+ struct pci_device **dvpp, *dvp;
+
+ dvpp = (struct pci_device **)pcidevice_set.ls_items;
+ while ((dvp = *dvpp++) != NULL) {
+ driver_t *driver;
+ driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT);
+ if (!driver)
+ continue;
+ bzero(driver, sizeof(driver_t));
+ driver->name = dvp->pd_name;
+ driver->methods = pci_compat_methods;
+ driver->type = 0; /* XXX fixup in pci_map_int() */
+ driver->softc = sizeof(struct pci_devinfo *);
+ driver->priv = dvp;
+ devclass_add_driver(pci_devclass, driver);
+ }
+}
+
+/*
+ * New style pci driver. Parent device is either a pci-host-bridge or a
+ * pci-pci-bridge. Both kinds are represented by instances of pcib.
+ */
+
+static void
+pci_print_verbose(struct pci_devinfo *dinfo)
+{
+ if (bootverbose) {
+ int i;
+ pcicfgregs *cfg = &dinfo->cfg;
+
+ printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
+ cfg->vendor, cfg->device, cfg->revid);
+ printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
+ cfg->baseclass, cfg->subclass, cfg->progif,
+ cfg->hdrtype, cfg->mfdev);
+ printf("\tsubordinatebus=%x \tsecondarybus=%x\n",
+ cfg->subordinatebus, cfg->secondarybus);
+#ifdef PCI_DEBUG
+ printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
+ cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
+ printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
+ cfg->lattimer, cfg->lattimer * 30,
+ cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
+#endif /* PCI_DEBUG */
+ if (cfg->intpin > 0)
+ printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
+
+ for (i = 0; i < cfg->nummaps; i++) {
+ pcimap *m = &cfg->map[i];
+ printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n",
+ i, m->type, m->ln2range, m->base, m->ln2size);
+ }
+ }
+}
+
+static int
+pci_add_children(device_t dev, int busno)
+{
+ pcicfgregs probe;
+ int bushigh = busno;
+
+#ifdef SIMOS
+#undef PCI_SLOTMAX
+#define PCI_SLOTMAX 0
+#endif
+
+ bzero(&probe, sizeof probe);
+ /* XXX KDM */
+ /* probe.parent = pci_bridgeto(bus); */
+ probe.bus = busno;
+ for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) {
+ int pcifunchigh = 0;
+ for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) {
+ struct pci_devinfo *dinfo = pci_readcfg(&probe);
+ if (dinfo != NULL) {
+ if (dinfo->cfg.mfdev)
+ pcifunchigh = 7;
+
+ pci_print_verbose(dinfo);
+ dinfo->cfg.dev =
+ device_add_child(dev, NULL, -1, dinfo);
+
+ if (bushigh < dinfo->cfg.subordinatebus)
+ bushigh = dinfo->cfg.subordinatebus;
+ if (bushigh < dinfo->cfg.secondarybus)
+ bushigh = dinfo->cfg.secondarybus;
+ }
+ }
+ }
+
+ return bushigh;
+}
+
+static int
+pci_new_probe(device_t dev)
+{
+ STAILQ_INIT(&pci_devq);
+ device_set_desc(dev, "PCI bus");
+
+ pci_add_children(dev, device_get_unit(dev));
+
+ return 0;
+}
+
+static void
+pci_print_child(device_t dev, device_t child)
+{
+ printf(" at device %d.%d", pci_get_slot(child), pci_get_function(child));
+ printf(" on %s%d", device_get_name(dev), device_get_unit(dev));
+}
+
+static int
+pci_read_ivar(device_t dev, device_t child, int which, u_long *result)
+{
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+
+ dinfo = device_get_ivars(child);
+ cfg = &dinfo->cfg;
+
+ switch (which) {
+ case PCI_IVAR_SUBVENDOR:
+ *result = cfg->subvendor;
+ break;
+ case PCI_IVAR_SUBDEVICE:
+ *result = cfg->subdevice;
+ break;
+ case PCI_IVAR_VENDOR:
+ *result = cfg->vendor;
+ break;
+ case PCI_IVAR_DEVICE:
+ *result = cfg->device;
+ break;
+ case PCI_IVAR_DEVID:
+ *result = (cfg->device << 16) | cfg->vendor;
+ break;
+ case PCI_IVAR_CLASS:
+ *result = cfg->baseclass;
+ break;
+ case PCI_IVAR_SUBCLASS:
+ *result = cfg->subclass;
+ break;
+ case PCI_IVAR_PROGIF:
+ *result = cfg->progif;
+ break;
+ case PCI_IVAR_REVID:
+ *result = cfg->revid;
+ break;
+ case PCI_IVAR_INTPIN:
+ *result = cfg->intpin;
+ break;
+ case PCI_IVAR_IRQ:
+ *result = cfg->intline;
+ break;
+ case PCI_IVAR_BUS:
+ *result = cfg->bus;
+ break;
+ case PCI_IVAR_SLOT:
+ *result = cfg->slot;
+ break;
+ case PCI_IVAR_FUNCTION:
+ *result = cfg->func;
+ break;
+ case PCI_IVAR_SECONDARYBUS:
+ *result = cfg->secondarybus;
+ break;
+ case PCI_IVAR_SUBORDINATEBUS:
+ *result = cfg->subordinatebus;
+ break;
+ default:
+ return ENOENT;
+ }
+ return 0;
+}
+
+static int
+pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+
+ dinfo = device_get_ivars(child);
+ cfg = &dinfo->cfg;
+
+ switch (which) {
+ case PCI_IVAR_SUBVENDOR:
+ case PCI_IVAR_SUBDEVICE:
+ case PCI_IVAR_VENDOR:
+ case PCI_IVAR_DEVICE:
+ case PCI_IVAR_DEVID:
+ case PCI_IVAR_CLASS:
+ case PCI_IVAR_SUBCLASS:
+ case PCI_IVAR_PROGIF:
+ case PCI_IVAR_REVID:
+ case PCI_IVAR_INTPIN:
+ case PCI_IVAR_IRQ:
+ case PCI_IVAR_BUS:
+ case PCI_IVAR_SLOT:
+ case PCI_IVAR_FUNCTION:
+ return EINVAL; /* disallow for now */
+
+ case PCI_IVAR_SECONDARYBUS:
+ cfg->secondarybus = value;
+ break;
+ case PCI_IVAR_SUBORDINATEBUS:
+ cfg->subordinatebus = value;
+ break;
+ default:
+ return ENOENT;
+ }
+ return 0;
+}
+
+static int
+pci_mapno(pcicfgregs *cfg, int reg)
+{
+ int i, nummaps;
+ pcimap *map;
+
+ nummaps = cfg->nummaps;
+ map = cfg->map;
+
+ for (i = 0; i < nummaps; i++)
+ if (map[i].reg == reg)
+ return (i);
+ return (-1);
+}
+
+static int
+pci_porten(pcicfgregs *cfg)
+{
+ return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0);
+}
+
+static int
+pci_isportmap(pcicfgregs *cfg, int map)
+
+{
+ return ((unsigned)map < cfg->nummaps
+ && (cfg->map[map].type & PCI_MAPPORT) != 0);
+}
+
+static int
+pci_memen(pcicfgregs *cfg)
+{
+ return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0);
+}
+
+static int
+pci_ismemmap(pcicfgregs *cfg, int map)
+{
+ return ((unsigned)map < cfg->nummaps
+ && (cfg->map[map].type & PCI_MAPMEM) != 0);
+}
+
+static struct resource *
+pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ int isdefault;
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ struct resource *rv, **rvp = 0;
+ int map;
+
+ isdefault = (device_get_parent(child) == dev
+ && start == 0UL && end == ~0UL && count == 1);
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (*rid != 0)
+ return 0;
+ if (isdefault && cfg->intline != 255) {
+ start = cfg->intline;
+ end = cfg->intline;
+ count = 1;
+ }
+ break;
+
+ case SYS_RES_DRQ: /* passthru for child isa */
+ break;
+
+ case SYS_RES_MEMORY:
+ if (isdefault) {
+ map = pci_mapno(cfg, *rid);
+ if (pci_memen(cfg) && pci_ismemmap(cfg, map)) {
+ start = cfg->map[map].base;
+ count = 1 << cfg->map[map].ln2size;
+ end = start + count;
+ rvp = &cfg->map[map].res;
+ } else
+ return 0;
+ }
+ break;
+
+ case SYS_RES_IOPORT:
+ if (isdefault) {
+ map = pci_mapno(cfg, *rid);
+ if (pci_porten(cfg) && pci_isportmap(cfg, map)) {
+ start = cfg->map[map].base;
+ count = 1 << cfg->map[map].ln2size;
+ end = start + count;
+ rvp = &cfg->map[map].res;
+ } else
+ return 0;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+
+ rv = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ type, rid, start, end, count, flags);
+ if (rvp)
+ *rvp = rv;
+
+ return rv;
+}
+
+static int
+pci_release_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ int rv;
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ int map = 0;
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (rid != 0)
+ return EINVAL;
+ break;
+
+ case SYS_RES_DRQ: /* passthru for child isa */
+ break;
+
+ case SYS_RES_MEMORY:
+ case SYS_RES_IOPORT:
+ /*
+ * Only check the map registers if this is a direct
+ * descendant.
+ */
+ if (device_get_parent(child) == dev)
+ map = pci_mapno(cfg, rid);
+ else
+ map = -1;
+ break;
+
+ default:
+ return (ENOENT);
+ }
+
+ rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r);
+
+ if (rv == 0) {
+ switch (type) {
+ case SYS_RES_IRQ:
+ cfg->irqres = 0;
+ break;
+
+ case SYS_RES_DRQ: /* passthru for child isa */
+ break;
+
+ case SYS_RES_MEMORY:
+ case SYS_RES_IOPORT:
+ if (map != -1)
+ cfg->map[map].res = 0;
+ break;
+
+ default:
+ return ENOENT;
+ }
+ }
+
+ return rv;
+}
+
+static u_int32_t
+pci_read_config_method(device_t dev, device_t child, int reg, int width)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ return pci_cfgread(cfg, reg, width);
+}
+
+static void
+pci_write_config_method(device_t dev, device_t child, int reg,
+ u_int32_t val, int width)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ pci_cfgwrite(cfg, reg, val, width);
+}
+
+static int
+pci_modevent(module_t mod, int what, void *arg)
+{
+ switch (what) {
+ case MOD_LOAD:
+ pci_wrap_old_drivers();
+ break;
+
+ case MOD_UNLOAD:
+ break;
+ }
+
+ return 0;
+}
+
+static device_method_t pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pci_new_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, pci_print_child),
+ DEVMETHOD(bus_read_ivar, pci_read_ivar),
+ DEVMETHOD(bus_write_ivar, pci_write_ivar),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+ DEVMETHOD(bus_alloc_resource, pci_alloc_resource),
+ DEVMETHOD(bus_release_resource, pci_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ /* PCI interface */
+ DEVMETHOD(pci_read_config, pci_read_config_method),
+ DEVMETHOD(pci_write_config, pci_write_config_method),
+
+ { 0, 0 }
+};
+
+static driver_t pci_driver = {
+ "pci",
+ pci_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+
+DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0);
+
#endif /* NPCI > 0 */
diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m
new file mode 100644
index 0000000..b2fa675
--- /dev/null
+++ b/sys/dev/pci/pci_if.m
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 1998 Doug Rabson
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+INTERFACE pci;
+
+METHOD u_int32_t read_config {
+ device_t dev;
+ device_t child;
+ int reg;
+ int width;
+};
+
+METHOD void write_config {
+ device_t dev;
+ device_t child;
+ int reg;
+ u_int32_t val;
+ int width;
+};
diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h
index 0adb540..9c0dba0 100644
--- a/sys/dev/pci/pcireg.h
+++ b/sys/dev/pci/pcireg.h
@@ -26,7 +26,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: pcireg.h,v 1.19 1997/09/20 07:41:58 dyson Exp $
+ * $Id: pcireg.h,v 1.20 1998/10/07 03:40:51 gibbs Exp $
*
*/
@@ -173,7 +173,7 @@
#define PCIS_MEMORY_OTHER 0x80
#define PCIC_BRIDGE 0x06
-#define PCIS_BRDIGE_HOST 0x00
+#define PCIS_BRIDGE_HOST 0x00
#define PCIS_BRIDGE_ISA 0x01
#define PCIS_BRIDGE_EISA 0x02
#define PCIS_BRIDGE_MCA 0x03
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 7843e3a..55f72a1 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -23,7 +23,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: pcivar.h,v 1.24 1999/01/13 04:59:19 bde Exp $
+ * $Id: pcivar.h,v 1.25 1999/01/19 23:29:20 se Exp $
*
*/
@@ -67,13 +67,17 @@ typedef struct {
u_int8_t ln2size;
u_int8_t ln2range;
u_int8_t reg; /* offset of map register in config space */
+/* u_int8_t dummy;*/
+ struct resource *res; /* handle from resource manager */
} pcimap;
/* config header information common to all header types */
typedef struct pcicfg {
+ struct device *dev; /* device which owns this */
pcimap *map; /* pointer to array of PCI maps */
void *hdrspec; /* pointer to header type specific data */
+ struct resource *irqres; /* resource descriptor for interrupt mapping */
u_int16_t subvendor; /* card vendor ID */
u_int16_t subdevice; /* card device ID, assigned by card vendor */
@@ -182,6 +186,79 @@ void pci_cfgwrite (pcicfgregs *cfg, int reg, int data, int bytes);
vm_offset_t pci_cvt_to_dense (vm_offset_t);
vm_offset_t pci_cvt_to_bwx (vm_offset_t);
#endif /* __alpha__ */
+
+#ifdef _SYS_BUS_H_
+
+#include "pci_if.h"
+
+enum pci_device_ivars {
+ PCI_IVAR_SUBVENDOR,
+ PCI_IVAR_SUBDEVICE,
+ PCI_IVAR_VENDOR,
+ PCI_IVAR_DEVICE,
+ PCI_IVAR_DEVID,
+ PCI_IVAR_CLASS,
+ PCI_IVAR_SUBCLASS,
+ PCI_IVAR_PROGIF,
+ PCI_IVAR_REVID,
+ PCI_IVAR_INTPIN,
+ PCI_IVAR_IRQ,
+ PCI_IVAR_BUS,
+ PCI_IVAR_SLOT,
+ PCI_IVAR_FUNCTION,
+ PCI_IVAR_SECONDARYBUS,
+ PCI_IVAR_SUBORDINATEBUS,
+};
+
+/*
+ * Simplified accessors for pci devices
+ */
+#define PCI_ACCESSOR(A, B, T) \
+ \
+static __inline T pci_get_ ## A(device_t dev) \
+{ \
+ uintptr_t v; \
+ BUS_READ_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, &v); \
+ return (T) v; \
+} \
+ \
+static __inline void pci_set_ ## A(device_t dev, T t) \
+{ \
+ u_long v = (u_long) t; \
+ BUS_WRITE_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, v); \
+}
+
+PCI_ACCESSOR(subvendor, SUBVENDOR, u_int16_t)
+PCI_ACCESSOR(subdevice, SUBDEVICE, u_int16_t)
+PCI_ACCESSOR(vendor, VENDOR, u_int16_t)
+PCI_ACCESSOR(device, DEVICE, u_int16_t)
+PCI_ACCESSOR(devid, DEVID, u_int32_t)
+PCI_ACCESSOR(class, CLASS, u_int8_t)
+PCI_ACCESSOR(subclass, SUBCLASS, u_int8_t)
+PCI_ACCESSOR(progif, PROGIF, u_int8_t)
+PCI_ACCESSOR(revid, REVID, u_int8_t)
+PCI_ACCESSOR(intpin, INTPIN, u_int8_t)
+PCI_ACCESSOR(irq, IRQ, u_int8_t)
+PCI_ACCESSOR(bus, BUS, u_int8_t)
+PCI_ACCESSOR(slot, SLOT, u_int8_t)
+PCI_ACCESSOR(function, FUNCTION, u_int8_t)
+PCI_ACCESSOR(secondarybus, SECONDARYBUS, u_int8_t)
+PCI_ACCESSOR(subordinatebus, SUBORDINATEBUS, u_int8_t)
+
+static __inline u_int32_t
+pci_read_config(device_t dev, int reg, int width)
+{
+ return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width);
+}
+
+static __inline void
+pci_write_config(device_t dev, int reg, u_int32_t val, int width)
+{
+ PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width);
+}
+
+#endif
+
/* for compatibility to FreeBSD-2.2 version of PCI code */
#ifdef PCI_COMPAT
diff --git a/sys/dev/rp/rp.c b/sys/dev/rp/rp.c
index 3ac4ee9..e9357fa 100644
--- a/sys/dev/rp/rp.c
+++ b/sys/dev/rp/rp.c
@@ -1180,7 +1180,6 @@ int
rpattach(dev)
struct isa_device *dev;
{
- struct isa_device *idev;
dev_t rp_dev;
int iobase, unit, /*rpmajor,*/ oldspl;
int num_ports, num_chan, num_aiops;
@@ -1280,13 +1279,6 @@ struct isa_device *dev;
}
}
- idev = find_isadev(isa_devtab_tty, &rpdriver,
- RP_MPMASTER(dev) + rp_pcicount);
- if(idev == NULL) {
- printf("rp%d: master device %d not configured\n",
- dev->id_unit, RP_MPMASTER(dev));
- }
-/* printf("COOL!! Device is found!!\n");
for(rpmajor=0;rpmajor<nchrdev;rpmajor++)
if(cdevsw[rpmajor].d_open == rpopen)
printf("From %d entries: Found entry at major = %d\n",nchrdev,rpmajor);
diff --git a/sys/dev/sio/sio.c b/sys/dev/sio/sio.c
index ee031b4..1a40360 100644
--- a/sys/dev/sio/sio.c
+++ b/sys/dev/sio/sio.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sio.c,v 1.220 1999/01/19 00:21:47 peter Exp $
+ * $Id: sio.c,v 1.221 1999/01/30 12:17:35 phk Exp $
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
* from: i386/isa sio.c,v 1.215
*/
@@ -68,6 +68,7 @@
#include <sys/syslog.h>
#include <sys/sysctl.h>
#include <sys/bus.h>
+#include <machine/bus.h>
#include <sys/rman.h>
#ifdef DEVFS
#include <sys/devfsext.h>
@@ -103,8 +104,10 @@
#endif
+#ifndef __i386__
#define disable_intr() 0
#define enable_intr() 0
+#endif
#ifdef SMP
#define disable_intr() COM_DISABLE_INTR()
@@ -2607,6 +2610,21 @@ 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.
+ */
+static cn_probe_t siocnprobe;
+static cn_init_t siocninit;
+static cn_checkc_t siocncheckc;
+ cn_getc_t siocngetc;
+ cn_putc_t siocnputc;
+
+CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
+
+#endif
+
static void
siocntxwait(iobase)
Port_t iobase;
@@ -2731,11 +2749,9 @@ void
siocnprobe(cp)
struct consdev *cp;
{
-#if 0
speed_t boot_speed;
u_char cfcr;
- struct isa_device *dvp;
- int s;
+ int s, unit;
struct siocnstate sp;
/*
@@ -2753,10 +2769,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,
@@ -2784,17 +2806,19 @@ siocnprobe(cp)
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;
}
-#endif
+ }
}
+#ifdef __alpha__
+
struct consdev siocons = {
NULL, NULL, siocngetc, siocncheckc, siocnputc,
NULL, makedev(CDEV_MAJOR, 0), CN_NORMAL,
@@ -2877,6 +2901,8 @@ siogdbattach(port, speed)
return 0;
}
+#endif
+
void
siocninit(cp)
struct consdev *cp;
@@ -3158,7 +3184,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;
@@ -3180,9 +3205,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)
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index a874dbb..a2db9b4 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/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.298 1999/02/05 11:52:11 yokota Exp $
+ * $Id: syscons.c,v 1.299 1999/03/10 10:36:53 yokota Exp $
*/
#include "sc.h"
@@ -1869,6 +1869,7 @@ extern struct isa_driver scdriver;
static void
sccnprobe(struct consdev *cp)
{
+#if 0
struct isa_device *dvp;
/*
@@ -1885,6 +1886,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/dev/usb/ohci.c b/sys/dev/usb/ohci.c
index 334a998..b97fee0 100644
--- a/sys/dev/usb/ohci.c
+++ b/sys/dev/usb/ohci.c
@@ -59,6 +59,10 @@
#include <sys/queue.h>
#include <sys/select.h>
+#ifdef __FreeBSD__
+#include <machine/bus_pio.h>
+#include <machine/bus_memio.h>
+#endif
#include <machine/bus.h>
#include <machine/endian.h>
@@ -162,15 +166,9 @@ void ohci_dump_td __P((ohci_soft_td_t *));
void ohci_dump_ed __P((ohci_soft_ed_t *));
#endif
-#if defined(__NetBSD__)
#define OWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
#define OREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
#define OREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
-#elif defined(__FreeBSD__)
-#define OWRITE4(sc, r, x) *(u_int32_t *) ((sc)->sc_iobase + (r)) = x
-#define OREAD4(sc, r) (*(u_int32_t *) ((sc)->sc_iobase + (r)))
-#define OREAD2(sc, r) (*(u_int16_t *) ((sc)->sc_iobase + (r)))
-#endif
/* Reverse the bits in a value 0 .. 31 */
static u_int8_t revbits[OHCI_NO_INTRS] =
diff --git a/sys/dev/usb/ohci_pci.c b/sys/dev/usb/ohci_pci.c
index 3c20ff7..1aea5f1 100644
--- a/sys/dev/usb/ohci_pci.c
+++ b/sys/dev/usb/ohci_pci.c
@@ -44,6 +44,8 @@
* USB spec: http://www.teleport.com/cgi-bin/mailmerge.cgi/~usb/cgiform.tpl
*/
+#include "opt_bus.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -52,23 +54,13 @@
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/queue.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
-#define PCI_CLASS_SERIALBUS 0x0c000000
-#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x00010000
-#define PCI_SUBCLASS_SERIALBUS_SSA 0x00020000
-#define PCI_SUBCLASS_SERIALBUS_USB 0x00030000
-#define PCI_SUBCLASS_SERIALBUS_FIBER 0x00040000
-
-#define PCI_INTERFACE(d) (((d) >> 8) & 0xff)
-#define PCI_SUBCLASS(d) ((d) & PCI_SUBCLASS_MASK)
-#define PCI_CLASS(d) ((d) & PCI_CLASS_MASK)
-
-
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
@@ -77,7 +69,6 @@
#include <dev/usb/ohcireg.h>
#include <dev/usb/ohcivar.h>
-
#define PCI_OHCI_VENDORID_ALI 0x10b9
#define PCI_OHCI_VENDORID_CMDTECH 0x1095
#define PCI_OHCI_VENDORID_COMPAQ 0x0e11
@@ -98,27 +89,12 @@ static const char *ohci_device_usb0673 = "CMD Tech 673 (USB0673) USB Host Contr
static const char *ohci_device_generic = "OHCI (generic) USB Host Controller";
-
-static const char *ohci_pci_probe __P((pcici_t, pcidi_t));
-static void ohci_pci_attach __P((pcici_t, int));
-
-static u_long ohci_count = 0;
-
-static struct pci_device ohci_pci_device = {
- "ohci",
- ohci_pci_probe,
- ohci_pci_attach,
- &ohci_count,
- NULL
-};
-
-DATA_SET(pcidevice_set, ohci_pci_device);
-
+#define PCI_OHCI_BASE_REG 0x10
static const char *
-ohci_pci_probe(pcici_t config_id, pcidi_t device_id)
+ohci_pci_match(device_t dev)
{
- u_int32_t class;
+ u_int32_t device_id = pci_get_devid(dev);
switch(device_id) {
case PCI_OHCI_DEVICEID_ALADDIN_V:
@@ -132,54 +108,72 @@ ohci_pci_probe(pcici_t config_id, pcidi_t device_id)
case PCI_OHCI_DEVICEID_NEC:
return (ohci_device_nec);
default:
- class = pci_conf_read(config_id, PCI_CLASS_REG);
- if ( (PCI_CLASS(class) == PCI_CLASS_SERIALBUS)
- && (PCI_SUBCLASS(class) == PCI_SUBCLASS_SERIALBUS_USB)
- && (PCI_INTERFACE(class) == PCI_INTERFACE_OHCI)) {
- return(ohci_device_generic);
+ if ( pci_get_class(dev) == PCIC_SERIALBUS
+ && pci_get_subclass(dev) == PCIS_SERIALBUS_USB
+ && pci_get_progif(dev) == PCI_INTERFACE_OHCI) {
+ return (ohci_device_generic);
}
}
return NULL; /* dunno */
}
-static void
-ohci_pci_attach(pcici_t config_id, int unit)
+static int
+ohci_pci_probe(device_t dev)
{
- vm_offset_t pbase;
+ const char *desc = ohci_pci_match(dev);
+ if (desc) {
+ device_set_desc(dev, desc);
+ return 0;
+ } else {
+ return ENXIO;
+ }
+}
+
+static int
+ohci_pci_attach(device_t dev)
+{
+ int unit = device_get_unit(dev);
+ ohci_softc_t *sc = device_get_softc(dev);
device_t usbus;
- ohci_softc_t *sc;
usbd_status err;
- int id;
+ int rid;
+ struct resource *res;
+ void *ih;
+ int error;
+
+ rid = PCI_CBMEM;
+ res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!res) {
+ device_printf(dev, "could not map memory\n");
+ return ENXIO;
+ }
- sc = malloc(sizeof(ohci_softc_t), M_DEVBUF, M_NOWAIT);
- /* Do not free it below, intr might use the sc */
- if ( sc == NULL ) {
- printf("ohci%d: could not allocate memory", unit);
- return;
- }
- memset(sc, 0, sizeof(ohci_softc_t));
+ sc->iot = rman_get_bustag(res);
+ sc->ioh = rman_get_bushandle(res);
- if(!pci_map_mem(config_id, PCI_CBMEM,
- (vm_offset_t *)&sc->sc_iobase, &pbase)) {
- printf("ohci%d: could not map memory\n", unit);
- return;
- }
+ rid = 0;
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (res == NULL) {
+ device_printf(dev, "could not allocate irq\n");
+ return ENOMEM;
+ }
- if ( !pci_map_int(config_id, (pci_inthand_t *)ohci_intr,
- (void *) sc, &bio_imask)) {
- printf("ohci%d: could not map irq\n", unit);
- return;
+ error = bus_setup_intr(dev, res, (driver_intr_t *) ohci_intr, sc, &ih);
+ if (error) {
+ device_printf(dev, "could not setup irq\n");
+ return error;
}
- usbus = device_add_child(root_bus, "usb", -1, sc);
+ usbus = device_add_child(dev, "usb", -1, sc);
if (!usbus) {
- printf("ohci%d: could not add USB device to root bus\n", unit);
- return;
+ printf("ohci%d: could not add USB device\n", unit);
+ return ENOMEM;
}
- id = pci_conf_read(config_id, PCI_ID_REG);
- switch(id) {
+ switch (pci_get_devid(dev)) {
case PCI_OHCI_DEVICEID_ALADDIN_V:
device_set_desc(usbus, ohci_device_aladdin_v);
sprintf(sc->sc_vendor, "AcerLabs");
@@ -202,7 +196,7 @@ ohci_pci_attach(pcici_t config_id, int unit)
break;
default:
if (bootverbose)
- printf("(New OHCI DeviceId=0x%08x)\n", id);
+ printf("(New OHCI DeviceId=0x%08x)\n", pci_get_devid(dev));
device_set_desc(usbus, ohci_device_generic);
sprintf(sc->sc_vendor, "(unknown)");
}
@@ -211,8 +205,36 @@ ohci_pci_attach(pcici_t config_id, int unit)
err = ohci_init(sc);
if (err != USBD_NORMAL_COMPLETION) {
printf("ohci%d: init failed, error=%d\n", unit, err);
- device_delete_child(root_bus, usbus);
+ device_delete_child(dev, usbus);
}
- return;
+ return device_probe_and_attach(sc->sc_bus.bdev);
}
+
+static device_method_t ohci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ohci_pci_probe),
+ DEVMETHOD(device_attach, ohci_pci_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t ohci_driver = {
+ "ohci",
+ ohci_methods,
+ DRIVER_TYPE_BIO,
+ sizeof(ohci_softc_t),
+};
+
+static devclass_t ohci_devclass;
+
+DRIVER_MODULE(ohci, pci, ohci_driver, ohci_devclass, 0, 0);
diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h
index 9063073..b485f50 100644
--- a/sys/dev/usb/ohcivar.h
+++ b/sys/dev/usb/ohcivar.h
@@ -72,7 +72,8 @@ typedef struct ohci_softc {
/* XXX should keep track of all DMA memory */
#elif defined(__FreeBSD__)
- int sc_iobase;
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
#endif /* __FreeBSD__ */
usb_dma_t sc_hccadma;
diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c
index 07cc3f9..00bb152 100644
--- a/sys/dev/usb/ucom.c
+++ b/sys/dev/usb/ucom.c
@@ -126,13 +126,8 @@ USB_ATTACH(ucom)
static int
ucom_detach(device_t self)
{
- const char *devinfo = device_get_desc(self);
-
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
- if (devinfo) {
- device_set_desc(self, NULL);
- free((void *)devinfo, M_USB);
- }
+ device_set_desc(self, NULL);
return 0;
}
#endif
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c
index cbd9e1e..cc14a7d 100644
--- a/sys/dev/usb/ugen.c
+++ b/sys/dev/usb/ugen.c
@@ -992,13 +992,8 @@ ugenpoll(dev, events, p)
static int
ugen_detach(device_t self)
{
- const char *devinfo = device_get_desc(self);
-
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
- if (devinfo) {
- device_set_desc(self, NULL);
- free((void *)devinfo, M_USB);
- }
+ device_set_desc(self, NULL);
return 0;
}
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index 30c69fd..62cb106 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -63,6 +63,9 @@ cgiform.tpl
#include <sys/queue.h>
#include <sys/select.h>
+#if defined(__FreeBSD__)
+#include <machine/bus_pio.h>
+#endif
#include <machine/bus.h>
#include <dev/usb/usb.h>
@@ -225,11 +228,11 @@ void uhci_dump_td __P((uhci_soft_td_t *));
#define UREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
#define UREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
#elif defined(__FreeBSD__)
-#define UWRITE2(sc,r,x) outw((sc)->sc_iobase + (r), (x))
-#define UWRITE4(sc,r,x) outl((sc)->sc_iobase + (r), (x))
-#define UREAD1(sc,r) inb((sc)->sc_iobase + (r))
-#define UREAD2(sc,r) inw((sc)->sc_iobase + (r))
-#define UREAD4(sc,r) inl((sc)->sc_iobase + (r))
+#define UWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x))
+#define UWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
+#define UREAD1(sc, r) bus_space_read_1((sc)->iot, (sc)->ioh, (r))
+#define UREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
+#define UREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
#endif
#define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
diff --git a/sys/dev/usb/uhci_pci.c b/sys/dev/usb/uhci_pci.c
index 6ed3cee..4bddf8b 100644
--- a/sys/dev/usb/uhci_pci.c
+++ b/sys/dev/usb/uhci_pci.c
@@ -1,4 +1,4 @@
-/* FreeBSD $Id: uhci_pci.c,v 1.4 1999/04/06 23:09:58 n_hibma Exp $ */
+/* FreeBSD $Id: uhci_pci.c,v 1.5 1999/04/11 14:24:20 n_hibma Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -37,6 +37,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_bus.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -45,23 +47,13 @@
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/queue.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
-#define PCI_CLASS_SERIALBUS 0x0c000000
-#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x00010000
-#define PCI_SUBCLASS_SERIALBUS_SSA 0x00020000
-#define PCI_SUBCLASS_SERIALBUS_USB 0x00030000
-#define PCI_SUBCLASS_SERIALBUS_FIBER 0x00040000
-
-#define PCI_INTERFACE(d) (((d)>>8)&0xff)
-#define PCI_SUBCLASS(d) ((d)&PCI_SUBCLASS_MASK)
-#define PCI_CLASS(d) ((d)&PCI_CLASS_MASK)
-
-
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
@@ -70,7 +62,6 @@
#include <dev/usb/uhcireg.h>
#include <dev/usb/uhcivar.h>
-
#define PCI_UHCI_VENDORID_INTEL 0x8086
#define PCI_UHCI_VENDORID_VIA 0x1106
@@ -85,26 +76,10 @@ static const char *uhci_device_generic = "UHCI (generic) USB Controller";
#define PCI_UHCI_BASE_REG 0x20
-static const char *uhci_pci_probe __P((pcici_t, pcidi_t));
-static void uhci_pci_attach __P((pcici_t, int));
-
-static u_long uhci_count = 0;
-
-static struct pci_device uhci_pci_device = {
- "uhci",
- uhci_pci_probe,
- uhci_pci_attach,
- &uhci_count,
- NULL
-};
-
-DATA_SET(pcidevice_set, uhci_pci_device);
-
-
static const char *
-uhci_pci_probe(pcici_t config_id, pcidi_t device_id)
+uhci_pci_match(device_t dev)
{
- u_int32_t class;
+ u_int32_t device_id = pci_get_devid(dev);
if (device_id == PCI_UHCI_DEVICEID_PIIX3) {
return (uhci_device_piix3);
@@ -113,10 +88,9 @@ uhci_pci_probe(pcici_t config_id, pcidi_t device_id)
} else if (device_id == PCI_UHCI_DEVICEID_VT83C572) {
return (uhci_device_vt83c572);
} else {
- class = pci_conf_read(config_id, PCI_CLASS_REG);
- if ( PCI_CLASS(class) == PCI_CLASS_SERIALBUS
- && PCI_SUBCLASS(class) == PCI_SUBCLASS_SERIALBUS_USB
- && PCI_INTERFACE(class) == PCI_INTERFACE_UHCI) {
+ if ( pci_get_class(dev) == PCIC_SERIALBUS
+ && pci_get_subclass(dev) == PCIS_SERIALBUS_USB
+ && pci_get_progif(dev) == PCI_INTERFACE_UHCI) {
return (uhci_device_generic);
}
}
@@ -124,42 +98,64 @@ uhci_pci_probe(pcici_t config_id, pcidi_t device_id)
return NULL; /* dunno... */
}
-static void
-uhci_pci_attach(pcici_t config_id, int unit)
+static int
+uhci_pci_probe(device_t dev)
+{
+ const char *desc = uhci_pci_match(dev);
+ if (desc) {
+ device_set_desc(dev, desc);
+ return 0;
+ } else {
+ return ENXIO;
+ }
+}
+
+static int
+uhci_pci_attach(device_t dev)
{
- int id, legsup;
+ int unit = device_get_unit(dev);
+ int legsup;
char *typestr;
usbd_status err;
- uhci_softc_t *sc = NULL;
device_t usbus;
-
- sc = malloc(sizeof(uhci_softc_t), M_DEVBUF, M_NOWAIT);
- /* Do not free it below, intr might use the sc */
- if ( sc == NULL ) {
- printf("uhci%d: could not allocate memory", unit);
- return;
+ uhci_softc_t *sc = device_get_softc(dev);
+ int rid;
+ struct resource *res;
+ void *ih;
+ int error;
+
+ rid = PCI_UHCI_BASE_REG;
+ res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!res) {
+ device_printf(dev, "could not map ports\n");
+ return ENXIO;
+ }
+
+ sc->iot = rman_get_bustag(res);
+ sc->ioh = rman_get_bushandle(res);
+
+ rid = 0;
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (res == NULL) {
+ device_printf(dev, "could not allocate irq\n");
+ return ENOMEM;
}
- memset(sc, 0, sizeof(uhci_softc_t));
-
- if ( !pci_map_port(config_id, PCI_UHCI_BASE_REG, &sc->sc_iobase) ) {
- printf("uhci%d: could not map port\n", unit);
- return;
- }
-
- if ( !pci_map_int(config_id, (pci_inthand_t *)uhci_intr,
- (void *) sc, &bio_imask)) {
- printf("uhci%d: could not map irq\n", unit);
- return;
+
+ error = bus_setup_intr(dev, res, (driver_intr_t *) uhci_intr, sc, &ih);
+ if (error) {
+ device_printf(dev, "could not setup irq\n");
+ return error;
}
- usbus = device_add_child(root_bus, "usb", -1, sc);
+ usbus = device_add_child(dev, "usb", -1, sc);
if (!usbus) {
- printf("usb%d: could not add USB device to root bus\n", unit);
- return;
+ printf("usb%d: could not add USB device\n", unit);
+ return ENOMEM;
}
- id = pci_conf_read(config_id, PCI_ID_REG);
- switch (id) {
+ switch (pci_get_devid(dev)) {
case PCI_UHCI_DEVICEID_PIIX3:
device_set_desc(usbus, uhci_device_piix3);
sprintf(sc->sc_vendor, "Intel");
@@ -173,13 +169,13 @@ uhci_pci_attach(pcici_t config_id, int unit)
sprintf(sc->sc_vendor, "VIA");
break;
default:
- printf("(New UHCI DeviceId=0x%08x)\n", id);
+ printf("(New UHCI DeviceId=0x%08x)\n", pci_get_devid(dev));
device_set_desc(usbus, uhci_device_generic);
- sprintf(sc->sc_vendor, "(0x%08x)", id);
+ sprintf(sc->sc_vendor, "(0x%08x)", pci_get_devid(dev));
}
if (bootverbose) {
- switch(pci_conf_read(config_id, PCI_USBREV) & PCI_USBREV_MASK) {
+ switch(pci_read_config(dev, PCI_USBREV, 4) & PCI_USBREV_MASK) {
case PCI_USBREV_PRE_1_0:
typestr = "pre 1.0";
break;
@@ -191,25 +187,53 @@ uhci_pci_attach(pcici_t config_id, int unit)
break;
}
printf("uhci%d: USB version %s, chip rev. %d\n", unit, typestr,
- (int) pci_conf_read(config_id, PCIR_REVID) & 0xff);
+ pci_get_revid(dev));
}
- legsup = pci_conf_read(config_id, PCI_LEGSUP);
+ legsup = pci_read_config(dev, PCI_LEGSUP, 4);
if ( !(legsup & PCI_LEGSUP_USBPIRQDEN) ) {
#if ! (defined(USBVERBOSE) || defined(USB_DEBUG))
if (bootverbose)
#endif
printf("uhci%d: PIRQD enable not set\n", unit);
legsup |= PCI_LEGSUP_USBPIRQDEN;
- pci_conf_write(config_id, PCI_LEGSUP, legsup);
+ pci_write_config(dev, PCI_LEGSUP, legsup, 4);
}
sc->sc_bus.bdev = usbus;
err = uhci_init(sc);
if (err != USBD_NORMAL_COMPLETION) {
printf("uhci%d: init failed, error=%d\n", unit, err);
- device_delete_child(root_bus, usbus);
+ device_delete_child(dev, usbus);
}
- return;
+ return device_probe_and_attach(sc->sc_bus.bdev);
}
+
+static device_method_t uhci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, uhci_pci_probe),
+ DEVMETHOD(device_attach, uhci_pci_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t uhci_driver = {
+ "uhci",
+ uhci_methods,
+ DRIVER_TYPE_BIO,
+ sizeof(uhci_softc_t),
+};
+
+static devclass_t uhci_devclass;
+
+DRIVER_MODULE(uhci, pci, uhci_driver, uhci_devclass, 0, 0);
diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h
index 2171374..89fed85 100644
--- a/sys/dev/usb/uhcivar.h
+++ b/sys/dev/usb/uhcivar.h
@@ -125,7 +125,8 @@ typedef struct uhci_softc {
bus_dma_tag_t sc_dmatag; /* DMA tag */
/* XXX should keep track of all DMA memory */
#elif defined(__FreeBSD__)
- int sc_iobase;
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
#endif /* defined(__FreeBSD__) */
uhci_physaddr_t *sc_pframes;
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
index a55944b..e434556 100644
--- a/sys/dev/usb/uhid.c
+++ b/sys/dev/usb/uhid.c
@@ -200,13 +200,8 @@ USB_ATTACH(uhid)
static int
uhid_detach(device_t self)
{
- const char *devinfo = device_get_desc(self);
-
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
- if (devinfo) {
- device_set_desc(self, NULL);
- free((void *)devinfo, M_USB);
- }
+ device_set_desc(self, NULL);
return 0;
}
#endif
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
index 2f4029c..bf53c01 100644
--- a/sys/dev/usb/uhub.c
+++ b/sys/dev/usb/uhub.c
@@ -81,10 +81,15 @@ usbd_status uhub_init_port __P((struct usbd_port *));
void uhub_disconnect_port __P((struct usbd_port *up));
usbd_status uhub_explore __P((usbd_device_handle hub));
void uhub_intr __P((usbd_request_handle, usbd_private_handle, usbd_status));
+#ifdef __FreeBSD__
+#include "usb_if.h"
+static void uhub_disconnected __P((device_t));
+#endif
/* void uhub_disco __P((void *)); */
-USB_DECLARE_DRIVER(uhub);
+USB_DECLARE_DRIVER_INIT(uhub,
+ DEVMETHOD(usb_disconnected, uhub_disconnected));
#if defined(__FreeBSD__)
devclass_t uhubroot_devclass;
@@ -251,8 +256,8 @@ USB_ATTACH(uhub)
}
#if defined(__FreeBSD__)
-static int
-uhub_detach(device_t self)
+static void
+uhub_disconnected(device_t self)
{
struct uhub_softc *sc = device_get_softc(self);
struct usbd_port *up;
@@ -264,12 +269,20 @@ uhub_detach(device_t self)
nports = dev->hub->hubdesc.bNbrPorts;
for (p = 0; p < nports; p++) {
up = &sc->sc_hub->hub->ports[p];
- if (up->device)
+ if (up->device) {
uhub_disconnect_port(up);
+ }
}
- free(sc->sc_hub->hub, M_USB);
+ return;
+}
+static int
+uhub_detach(device_t self)
+{
+ struct uhub_softc *sc = device_get_softc(self);
+ DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
+ free(sc->sc_hub->hub, M_USB);
return 0;
}
#endif
@@ -502,6 +515,7 @@ uhub_disconnect_port(up)
}
}
#if defined(__FreeBSD__)
+ USB_DISCONNECTED(sc->sc_dev);
device_delete_child(scp->sc_dev, sc->sc_dev);
#endif
diff --git a/sys/dev/usb/ulpt.c b/sys/dev/usb/ulpt.c
index 0984460..9aaf024 100644
--- a/sys/dev/usb/ulpt.c
+++ b/sys/dev/usb/ulpt.c
@@ -437,13 +437,8 @@ ulptioctl(dev, cmd, data, flag, p)
static int
ulpt_detach(device_t self)
{
- const char *devinfo = device_get_desc(self);
-
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
- if (devinfo) {
- device_set_desc(self, NULL);
- free((void *)devinfo, M_USB);
- }
+ device_set_desc(self, NULL);
return 0;
}
diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c
index 7a1b600..c624b86 100644
--- a/sys/dev/usb/umodem.c
+++ b/sys/dev/usb/umodem.c
@@ -125,13 +125,8 @@ USB_ATTACH(umodem)
static int
umodem_detach(device_t self)
{
- const char *devinfo = device_get_desc(self);
-
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
- if (devinfo) {
- device_set_desc(self, NULL);
- free((void *)devinfo, M_USB);
- }
+ device_set_desc(self, NULL);
return 0;
}
diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c
index 9464566..4d3578b 100644
--- a/sys/dev/usb/ums.c
+++ b/sys/dev/usb/ums.c
@@ -363,7 +363,6 @@ static int
ums_detach(device_t self)
{
struct ums_softc *sc = device_get_softc(self);
- const char *devinfo = device_get_desc(self);
if (sc->sc_enabled) {
usbd_abort_pipe(sc->sc_intrpipe);
@@ -372,10 +371,7 @@ ums_detach(device_t self)
sc->sc_disconnected = 1;
DPRINTF(("%s: disconnected\n", USBDEVNAME(self)));
- if (devinfo) {
- device_set_desc(self, NULL);
- free((void *)devinfo, M_USB);
- }
+ device_set_desc(self, NULL);
free(sc->sc_loc_btn, M_USB);
free(sc->sc_ibuf, M_USB);
diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c
index 935f951..8d9689a 100644
--- a/sys/dev/usb/usb.c
+++ b/sys/dev/usb/usb.c
@@ -408,5 +408,6 @@ usb_detach(device_t self)
return (1);
}
-DRIVER_MODULE(usb, root, usb_driver, usb_devclass, 0, 0);
+DRIVER_MODULE(usb, uhci, usb_driver, usb_devclass, 0, 0);
+DRIVER_MODULE(usb, ohci, usb_driver, usb_devclass, 0, 0);
#endif
diff --git a/sys/dev/usb/usb_if.m b/sys/dev/usb/usb_if.m
index 2c5e521..62ea118 100644
--- a/sys/dev/usb/usb_if.m
+++ b/sys/dev/usb/usb_if.m
@@ -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: usb_if.m,v 1.3 1999/01/07 23:31:37 n_hibma Exp $
+# $Id: usb_if.m,v 1.4 1999/03/22 19:58:59 n_hibma Exp $
#
# USB interface description
@@ -38,3 +38,10 @@ INTERFACE usb;
METHOD int reconfigure {
device_t dev;
};
+
+# The device is being disconnected and should clean up before
+# being destroyed.
+#
+METHOD void disconnected {
+ device_t dev;
+};
diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h
index f1dd74a..ea144b9 100644
--- a/sys/dev/usb/usb_port.h
+++ b/sys/dev/usb/usb_port.h
@@ -126,7 +126,7 @@ __CONCAT(dname,_attach)(parent, self, aux) \
* because of includes in the wrong order.
*/
#define bdevice device_t
-#define USBDEVNAME(bdev) usbd_devname(&bdev)
+#define USBDEVNAME(bdev) device_get_nameunit(bdev)
/* XXX Change this when FreeBSD has memset
*/
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index d045a4d..8b88cd3 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -1302,30 +1302,7 @@ usbd_driver_load(module_t mod, int what, void *arg)
void
usbd_device_set_desc(device_t device, char *devinfo)
{
- size_t l;
- char *desc;
-
- if ( devinfo ) {
- l = strlen(devinfo);
- desc = malloc(l+1, M_USB, M_NOWAIT);
- if (desc)
- memcpy(desc, devinfo, l+1);
- } else
- desc = NULL;
-
- device_set_desc(device, desc);
-}
-
-char *
-usbd_devname(bdevice *bdev)
-{
- static char buf[20];
- /* XXX a static buffer is not exactly a good idea, but the only
- * thing that goes wrong is the string that is being printed
- */
-
- sprintf(buf, "%s%d", device_get_name(*bdev), device_get_unit(*bdev));
- return (buf);
+ device_set_desc_copy(device, devinfo);
}
#endif
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
index 8cdcfdb..7a41f8b 100644
--- a/sys/dev/usb/usbdi.h
+++ b/sys/dev/usb/usbdi.h
@@ -336,7 +336,6 @@ usb_endpoint_descriptor_t *usbd_get_endpoint_descriptor
#if defined(__FreeBSD__)
int usbd_driver_load __P((module_t mod, int what, void *arg));
void usbd_device_set_desc __P((device_t device, char *devinfo));
-char *usbd_devname(bdevice *bdev);
bus_print_child_t usbd_print_child;
#endif
diff --git a/sys/i386/apm/apm.c b/sys/i386/apm/apm.c
index 42515c8..359e99e 100644
--- a/sys/i386/apm/apm.c
+++ b/sys/i386/apm/apm.c
@@ -15,7 +15,7 @@
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
- * $Id: apm.c,v 1.76 1998/12/04 21:28:39 archie Exp $
+ * $Id: apm.c,v 1.77 1998/12/10 23:36:14 msmith Exp $
*/
#include "opt_devfs.h"
@@ -30,7 +30,7 @@
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/reboot.h>
-#include <i386/isa/isa_device.h>
+#include <sys/bus.h>
#include <machine/apm_bios.h>
#include <machine/segments.h>
#include <machine/clock.h>
@@ -432,11 +432,15 @@ void
apm_suspend(int state)
{
struct apm_softc *sc = &apm_softc;
+ int error;
if (!sc)
return;
if (sc->initialized) {
+ error = DEVICE_SUSPEND(root_bus);
+ if (error)
+ return; /* XXX no error reporting */
apm_execute_hook(hook[APM_HOOK_SUSPEND]);
if (apm_suspend_system(state) == 0)
apm_processevent();
@@ -454,8 +458,10 @@ apm_resume(void)
if (!sc)
return;
- if (sc->initialized)
+ if (sc->initialized) {
+ DEVICE_RESUME(root_bus);
apm_execute_hook(hook[APM_HOOK_RESUME]);
+ }
}
@@ -623,9 +629,6 @@ apm_not_halt_cpu(void)
}
/* device driver definitions */
-static int apmprobe (struct isa_device *);
-static int apmattach(struct isa_device *);
-struct isa_driver apmdriver = { apmprobe, apmattach, "apm" };
/*
* probe APM (dummy):
@@ -639,18 +642,24 @@ struct isa_driver apmdriver = { apmprobe, apmattach, "apm" };
*/
static int
-apmprobe(struct isa_device *dvp)
+apm_probe(device_t dev)
{
#ifdef VM86
struct vm86frame vmf;
int i;
#endif
+ int flags;
+
+ device_set_desc(dev, "APM BIOS");
- if ( dvp->id_unit > 0 ) {
+ if ( device_get_unit(dev) > 0 ) {
printf("apm: Only one APM driver supported.\n");
- return 0;
+ return ENXIO;
}
+ if (resource_int_value("apm", 0, "flags", &flags) != 0)
+ flags = 0;
+
#ifdef VM86
bzero(&vmf, sizeof(struct vm86frame)); /* safety */
vmf.vmf_ax = (APM_BIOS << 8) | APM_INSTCHECK;
@@ -712,9 +721,9 @@ apmprobe(struct isa_device *dvp)
printf("apm: 32-bit connection error.\n");
return 0;
}
- if (dvp->id_flags & 0x20)
+ if (flags & 0x20)
statclock_disable = 1;
- return -1;
+ return 0;
}
@@ -779,10 +788,14 @@ apm_processevent(void)
*/
static int
-apmattach(struct isa_device *dvp)
+apm_attach(device_t dev)
{
#define APM_KERNBASE KERNBASE
struct apm_softc *sc = &apm_softc;
+ int flags;
+
+ if (resource_int_value("apm", 0, "flags", &flags) != 0)
+ flags = 0;
sc->initialized = 0;
@@ -833,11 +846,11 @@ apmattach(struct isa_device *dvp)
apm_addr.segment = GSEL(GAPMCODE32_SEL, SEL_KPL);
apm_addr.offset = sc->cs_entry;
- if ((dvp->id_flags & 0x10)) {
- if ((dvp->id_flags & 0xf) >= 0x2) {
+ if ((flags & 0x10)) {
+ if ((flags & 0xf) >= 0x2) {
apm_driver_version(0x102);
}
- if (!apm_version && (dvp->id_flags & 0xf) >= 0x1) {
+ if (!apm_version && (flags & 0xf) >= 0x1) {
apm_driver_version(0x101);
}
} else {
@@ -1009,19 +1022,22 @@ apmioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
return error;
}
+static device_method_t apm_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, apm_probe),
+ DEVMETHOD(device_attach, apm_attach),
-static apm_devsw_installed = 0;
+ { 0, 0 }
+};
-static void
-apm_drvinit(void *unused)
-{
- dev_t dev;
+static driver_t apm_driver = {
+ "apm",
+ apm_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc (XXX) */
+};
- if( ! apm_devsw_installed ) {
- dev = makedev(CDEV_MAJOR,0);
- cdevsw_add(&dev,&apm_cdevsw,NULL);
- apm_devsw_installed = 1;
- }
-}
+static devclass_t apm_devclass;
-SYSINIT(apmdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,apm_drvinit,NULL)
+CDEV_DRIVER_MODULE(apm, nexus, apm_driver, apm_devclass,
+ CDEV_MAJOR, apm_cdevsw, 0, 0);
diff --git a/sys/i386/bios/apm.c b/sys/i386/bios/apm.c
index 42515c8..359e99e 100644
--- a/sys/i386/bios/apm.c
+++ b/sys/i386/bios/apm.c
@@ -15,7 +15,7 @@
*
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
*
- * $Id: apm.c,v 1.76 1998/12/04 21:28:39 archie Exp $
+ * $Id: apm.c,v 1.77 1998/12/10 23:36:14 msmith Exp $
*/
#include "opt_devfs.h"
@@ -30,7 +30,7 @@
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/reboot.h>
-#include <i386/isa/isa_device.h>
+#include <sys/bus.h>
#include <machine/apm_bios.h>
#include <machine/segments.h>
#include <machine/clock.h>
@@ -432,11 +432,15 @@ void
apm_suspend(int state)
{
struct apm_softc *sc = &apm_softc;
+ int error;
if (!sc)
return;
if (sc->initialized) {
+ error = DEVICE_SUSPEND(root_bus);
+ if (error)
+ return; /* XXX no error reporting */
apm_execute_hook(hook[APM_HOOK_SUSPEND]);
if (apm_suspend_system(state) == 0)
apm_processevent();
@@ -454,8 +458,10 @@ apm_resume(void)
if (!sc)
return;
- if (sc->initialized)
+ if (sc->initialized) {
+ DEVICE_RESUME(root_bus);
apm_execute_hook(hook[APM_HOOK_RESUME]);
+ }
}
@@ -623,9 +629,6 @@ apm_not_halt_cpu(void)
}
/* device driver definitions */
-static int apmprobe (struct isa_device *);
-static int apmattach(struct isa_device *);
-struct isa_driver apmdriver = { apmprobe, apmattach, "apm" };
/*
* probe APM (dummy):
@@ -639,18 +642,24 @@ struct isa_driver apmdriver = { apmprobe, apmattach, "apm" };
*/
static int
-apmprobe(struct isa_device *dvp)
+apm_probe(device_t dev)
{
#ifdef VM86
struct vm86frame vmf;
int i;
#endif
+ int flags;
+
+ device_set_desc(dev, "APM BIOS");
- if ( dvp->id_unit > 0 ) {
+ if ( device_get_unit(dev) > 0 ) {
printf("apm: Only one APM driver supported.\n");
- return 0;
+ return ENXIO;
}
+ if (resource_int_value("apm", 0, "flags", &flags) != 0)
+ flags = 0;
+
#ifdef VM86
bzero(&vmf, sizeof(struct vm86frame)); /* safety */
vmf.vmf_ax = (APM_BIOS << 8) | APM_INSTCHECK;
@@ -712,9 +721,9 @@ apmprobe(struct isa_device *dvp)
printf("apm: 32-bit connection error.\n");
return 0;
}
- if (dvp->id_flags & 0x20)
+ if (flags & 0x20)
statclock_disable = 1;
- return -1;
+ return 0;
}
@@ -779,10 +788,14 @@ apm_processevent(void)
*/
static int
-apmattach(struct isa_device *dvp)
+apm_attach(device_t dev)
{
#define APM_KERNBASE KERNBASE
struct apm_softc *sc = &apm_softc;
+ int flags;
+
+ if (resource_int_value("apm", 0, "flags", &flags) != 0)
+ flags = 0;
sc->initialized = 0;
@@ -833,11 +846,11 @@ apmattach(struct isa_device *dvp)
apm_addr.segment = GSEL(GAPMCODE32_SEL, SEL_KPL);
apm_addr.offset = sc->cs_entry;
- if ((dvp->id_flags & 0x10)) {
- if ((dvp->id_flags & 0xf) >= 0x2) {
+ if ((flags & 0x10)) {
+ if ((flags & 0xf) >= 0x2) {
apm_driver_version(0x102);
}
- if (!apm_version && (dvp->id_flags & 0xf) >= 0x1) {
+ if (!apm_version && (flags & 0xf) >= 0x1) {
apm_driver_version(0x101);
}
} else {
@@ -1009,19 +1022,22 @@ apmioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
return error;
}
+static device_method_t apm_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, apm_probe),
+ DEVMETHOD(device_attach, apm_attach),
-static apm_devsw_installed = 0;
+ { 0, 0 }
+};
-static void
-apm_drvinit(void *unused)
-{
- dev_t dev;
+static driver_t apm_driver = {
+ "apm",
+ apm_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc (XXX) */
+};
- if( ! apm_devsw_installed ) {
- dev = makedev(CDEV_MAJOR,0);
- cdevsw_add(&dev,&apm_cdevsw,NULL);
- apm_devsw_installed = 1;
- }
-}
+static devclass_t apm_devclass;
-SYSINIT(apmdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,apm_drvinit,NULL)
+CDEV_DRIVER_MODULE(apm, nexus, apm_driver, apm_devclass,
+ CDEV_MAJOR, apm_cdevsw, 0, 0);
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 60cc225..03e74ce 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/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: GENERIC,v 1.160 1999/04/16 16:17:05 n_hibma Exp $
+# $Id: GENERIC,v 1.161 1999/04/16 18:27:18 jkh Exp $
machine "i386"
cpu "I386_CPU"
@@ -53,10 +53,10 @@ 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 eisa0
-controller pci0
+controller isa0 at nexus?
+#controller pnp0 # PnP support for ISA
+#controller eisa0
+controller pci0 at nexus?
controller fdc0 at isa? port "IO_FD1" bio irq 6 drq 2
disk fd0 at fdc0 drive 0
@@ -108,9 +108,9 @@ controller matcd0 at isa? port 0x230 bio
device scd0 at isa? port 0x230 bio
# atkbdc0 controlls both the keyboard and the PS/2 mouse
-controller atkbdc0 at isa? port IO_KBD tty
-device atkbd0 at isa? tty irq 1
-device psm0 at isa? tty irq 12
+controller atkbdc0 at isa? port IO_KBD
+device atkbd0 at atkbdc? tty irq 1
+device psm0 at atkbdc? tty irq 12
device vga0 at isa? port ? conflicts
@@ -126,12 +126,12 @@ device sc0 at isa? tty
# If you have a ThinkPAD, uncomment this along with the rest of the PCVT lines
#options PCVT_SCANSET=2 # IBM keyboards are non-std
-device npx0 at isa? port IO_NPX irq 13
+device npx0 at nexus? port IO_NPX irq 13
#
# 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
@@ -178,8 +178,8 @@ device ex0 at isa? port? net irq?
device fe0 at isa? port 0x300 net irq ?
device le0 at isa? port 0x300 net irq 5 iomem 0xd0000
device lnc0 at isa? port 0x280 net irq 10 drq 0
-device ze0 at isa? port 0x300 net irq 10 iomem 0xd8000
-device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000
+#device ze0 at isa? port 0x300 net irq 10 iomem 0xd8000
+#device zp0 at isa? port 0x300 net irq 10 iomem 0xd8000
device cs0 at isa? port 0x300 net irq ?
pseudo-device loop
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index 833fbc9..20b284b 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.581 1999/04/14 16:54:00 peter Exp $
+# $Id: LINT,v 1.582 1999/04/16 16:17:04 n_hibma Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -827,7 +827,7 @@ options "MSGBUF_SIZE=40960"
#
# Mandatory ISA devices: isa, npx
#
-controller isa0
+controller isa0 at nexus?
#
# Options for `isa':
@@ -888,10 +888,10 @@ options "NTIMECOUNTER=20"
controller pnp0
# The keyboard controller; it controlls the keyboard and the PS/2 mouse.
-controller atkbdc0 at isa? port IO_KBD tty
+controller atkbdc0 at isa? port IO_KBD
# The AT keyboard
-device atkbd0 at isa? tty irq 1
+device atkbd0 at atkbdc? tty irq 1
# Options for atkbd:
options ATKBD_DFLT_KEYMAP # specify the built-in keymap
@@ -907,7 +907,7 @@ options KBD_INSTALL_CDEV # install a CDEV entry in /dev
# 0x04 Old-style (XT) keyboard support, useful for older ThinkPads
# PS/2 mouse
-device psm0 at isa? tty irq 12
+device psm0 at atkbdc? tty irq 12
# Options for psm:
options PSM_HOOKAPM #hook the APM resume event, useful
@@ -977,7 +977,7 @@ options SC_DISABLE_REBOOT # disable reboot key sequence
# buggy. If it is not configured then you *must* configure math emulation
# (see above). If both npx0 and emulation are configured, then only npx0
# is used (provided it works).
-device npx0 at isa? port IO_NPX iosiz 0x0 flags 0x0 irq 13
+device npx0 at nexus? port IO_NPX iosiz 0x0 flags 0x0 irq 13
#
# `flags' for npx0:
@@ -1464,7 +1464,7 @@ controller matcd0 at isa? port 0x230 bio
device wt0 at isa? port 0x300 bio irq 5 drq 1
device ctx0 at isa? port 0x230 iomem 0xd0000
device spigot0 at isa? port 0xad6 irq 15 iomem 0xee000
-device apm0 at isa?
+device apm0 at nexus?
device gp0 at isa? port 0x2c0 tty
device gsc0 at isa? port "IO_GSC1" tty drq 3
device joy0 at isa? port IO_GAME
@@ -1632,7 +1632,7 @@ options "EISA_SLOTS=12"
# The "oltr" driver supports the following Olicom PCI token-ring adapters
# OC-3136, OC-3137, OC-3139, OC-3140, OC-3141, OC-3540, OC-3250
#
-controller pci0
+controller pci0 at nexus?
controller ahc1
controller ncr0
controller isp0
diff --git a/sys/i386/conf/Makefile.i386 b/sys/i386/conf/Makefile.i386
index 9c9ba23..cf6a212 100644
--- a/sys/i386/conf/Makefile.i386
+++ b/sys/i386/conf/Makefile.i386
@@ -1,7 +1,7 @@
# Makefile.i386 -- with config changes.
# Copyright 1990 W. Jolitz
# from: @(#)Makefile.i386 7.1 5/10/91
-# $Id: Makefile.i386,v 1.144 1999/04/13 18:25:08 peter Exp $
+# $Id: Makefile.i386,v 1.145 1999/04/15 14:52:23 bde Exp $
#
# Makefile for FreeBSD
#
@@ -17,7 +17,7 @@
#
# Which version of config(8) is required.
-%VERSREQ= 300012
+%VERSREQ= 400013
KERNFORMAT?= elf
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 833fbc9..20b284b 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.581 1999/04/14 16:54:00 peter Exp $
+# $Id: LINT,v 1.582 1999/04/16 16:17:04 n_hibma Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -827,7 +827,7 @@ options "MSGBUF_SIZE=40960"
#
# Mandatory ISA devices: isa, npx
#
-controller isa0
+controller isa0 at nexus?
#
# Options for `isa':
@@ -888,10 +888,10 @@ options "NTIMECOUNTER=20"
controller pnp0
# The keyboard controller; it controlls the keyboard and the PS/2 mouse.
-controller atkbdc0 at isa? port IO_KBD tty
+controller atkbdc0 at isa? port IO_KBD
# The AT keyboard
-device atkbd0 at isa? tty irq 1
+device atkbd0 at atkbdc? tty irq 1
# Options for atkbd:
options ATKBD_DFLT_KEYMAP # specify the built-in keymap
@@ -907,7 +907,7 @@ options KBD_INSTALL_CDEV # install a CDEV entry in /dev
# 0x04 Old-style (XT) keyboard support, useful for older ThinkPads
# PS/2 mouse
-device psm0 at isa? tty irq 12
+device psm0 at atkbdc? tty irq 12
# Options for psm:
options PSM_HOOKAPM #hook the APM resume event, useful
@@ -977,7 +977,7 @@ options SC_DISABLE_REBOOT # disable reboot key sequence
# buggy. If it is not configured then you *must* configure math emulation
# (see above). If both npx0 and emulation are configured, then only npx0
# is used (provided it works).
-device npx0 at isa? port IO_NPX iosiz 0x0 flags 0x0 irq 13
+device npx0 at nexus? port IO_NPX iosiz 0x0 flags 0x0 irq 13
#
# `flags' for npx0:
@@ -1464,7 +1464,7 @@ controller matcd0 at isa? port 0x230 bio
device wt0 at isa? port 0x300 bio irq 5 drq 1
device ctx0 at isa? port 0x230 iomem 0xd0000
device spigot0 at isa? port 0xad6 irq 15 iomem 0xee000
-device apm0 at isa?
+device apm0 at nexus?
device gp0 at isa? port 0x2c0 tty
device gsc0 at isa? port "IO_GSC1" tty drq 3
device joy0 at isa? port IO_GAME
@@ -1632,7 +1632,7 @@ options "EISA_SLOTS=12"
# The "oltr" driver supports the following Olicom PCI token-ring adapters
# OC-3136, OC-3137, OC-3139, OC-3140, OC-3141, OC-3540, OC-3250
#
-controller pci0
+controller pci0 at nexus?
controller ahc1
controller ncr0
controller isp0
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 81f360e..ba0dba1 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -1,7 +1,7 @@
# This file tells config what files go into building a kernel,
# files marked standard are always included.
#
-# $Id: files.i386,v 1.234 1999/04/13 19:38:10 peter Exp $
+# $Id: files.i386,v 1.235 1999/04/15 14:52:23 bde Exp $
#
# The long compile-with and dependency lines are required because of
# limitations in config: backslash-newline doesn't work in strings, and
@@ -90,6 +90,7 @@ 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
@@ -125,8 +126,8 @@ i386/ibcs2/imgact_coff.c optional ibcs2
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/atkbd_isa.c optional atkbd device-driver
-i386/isa/atkbdc_isa.c optional atkbdc device-driver
+isa/atkbd_isa.c optional atkbd device-driver
+isa/atkbdc_isa.c optional atkbdc device-driver
i386/isa/bt_isa.c optional bt device-driver
i386/isa/clock.c standard
i386/isa/cronyx.c optional cx device-driver
@@ -177,6 +178,8 @@ i386/isa/mse.c optional mse device-driver
i386/isa/npx.c mandatory npx device-driver
i386/isa/pcaudio.c optional pca device-driver
i386/isa/matcd/matcd.c optional matcd device-driver
+i386/isa/isa_compat.c optional isa device-driver
+i386/isa/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
@@ -190,7 +193,7 @@ 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
@@ -198,7 +201,7 @@ i386/isa/scd.c optional scd device-driver
i386/isa/si.c optional si device-driver
i386/isa/si2_z280.c optional si device-driver
i386/isa/si3_t225.c optional si device-driver
-i386/isa/sio.c optional sio device-driver
+isa/sio.c optional sio device-driver
i386/isa/snd/sound.c optional pcm device-driver
i386/isa/snd/dmabuf.c optional pcm device-driver
i386/isa/snd/ad1848.c optional pcm device-driver
@@ -268,9 +271,9 @@ i386/isa/sound/cs4232.c optional css device-driver
i386/isa/spigot.c optional spigot device-driver
i386/isa/spkr.c optional speaker device-driver
i386/isa/stallion.c optional stl device-driver
-i386/isa/syscons_isa.c optional sc device-driver
+isa/syscons_isa.c optional sc device-driver
i386/isa/vesa.c optional vga device-driver
-i386/isa/vga_isa.c optional vga device-driver
+isa/vga_isa.c optional vga device-driver
i386/isa/tw.c optional tw device-driver
i386/isa/wd.c optional wdc device-driver
i386/isa/wd.c optional wd device-driver
diff --git a/sys/i386/i386/autoconf.c b/sys/i386/i386/autoconf.c
index fc7ab85..c501281 100644
--- a/sys/i386/i386/autoconf.c
+++ b/sys/i386/i386/autoconf.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)autoconf.c 7.1 (Berkeley) 5/9/91
- * $Id: autoconf.c,v 1.111 1999/01/19 00:10:59 peter Exp $
+ * $Id: autoconf.c,v 1.112 1999/04/15 14:52:24 bde Exp $
*/
/*
@@ -50,9 +50,11 @@
#include "opt_cd9660.h"
#include "opt_mfs.h"
#include "opt_nfsroot.h"
+#include "opt_bus.h"
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/disklabel.h>
#include <sys/diskslice.h>
@@ -74,13 +76,19 @@
#include "isa.h"
#if NISA > 0
+#ifdef OLD_BUS_ARCH
#include <i386/isa/isa_device.h>
+#else
+device_t isa_bus_device = 0;
+#endif /* OLD_BUS_ARCH */
#endif
#include "pnp.h"
#if NPNP > 0
+#ifdef OLD_BUS_ARCH
#include <i386/isa/pnp.h>
#endif
+#endif
#include "eisa.h"
#if NEISA > 0
@@ -92,8 +100,6 @@
#include <pci/pcivar.h>
#endif
-#include <sys/bus.h>
-
static void configure_first __P((void *));
static void configure __P((void *));
static void configure_final __P((void *));
@@ -186,6 +192,8 @@ configure_finish()
{
}
+device_t nexus_dev;
+
/*
* Determine i/o configuration for a machine.
*/
@@ -228,21 +236,21 @@ configure(dummy)
eisa_configure();
#endif
-#if NPCI > 0
- pci_configure();
-#endif
-
#if NPNP > 0
pnp_configure();
#endif
-#if NISA > 0
- isa_configure();
-#endif
+ /* nexus0 is the top of the i386 device tree */
+ device_add_child(root_bus, "nexus", 0, 0);
/* initialize new bus architecture */
root_bus_configure();
+#if NISA > 0
+ if (isa_bus_device)
+ bus_generic_attach(isa_bus_device);
+#endif
+
/*
* Now we're ready to handle (pending) interrupts.
* XXX this is slightly misplaced.
diff --git a/sys/i386/i386/exception.s b/sys/i386/i386/exception.s
index 79e1d1a..a9286fa 100644
--- a/sys/i386/i386/exception.s
+++ b/sys/i386/i386/exception.s
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: exception.s,v 1.56 1999/02/25 11:03:08 bde Exp $
+ * $Id: exception.s,v 1.57 1999/02/28 10:53:28 bde Exp $
*/
#include "npx.h"
@@ -139,7 +139,7 @@ IDTVEC(fpu)
#if NNPX > 0
/*
* Handle like an interrupt (except for accounting) so that we can
- * call npxintr to clear the error. It would be better to handle
+ * call npx_intr to clear the error. It would be better to handle
* npx interrupts as traps. This used to be difficult for nested
* interrupts, but now it is fairly easy - mask nested ones the
* same as SWI_AST's.
@@ -180,7 +180,7 @@ IDTVEC(fpu)
movl %eax,_cpl
#endif /* SMP */
- call _npxintr
+ call _npx_intr
incb _intr_nesting_level
MEXITCOUNT
diff --git a/sys/i386/i386/legacy.c b/sys/i386/i386/legacy.c
new file mode 100644
index 0000000..7df4387
--- /dev/null
+++ b/sys/i386/i386/legacy.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright 1998 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * This code implements a `root nexus' for Intel Architecture
+ * machines. The function of the root nexus is to serve as an
+ * attachment point for both processors and buses, and to manage
+ * resources which are common to all of them. In particular,
+ * this code implements the core resource managers for interrupt
+ * requests, DMA requests (which rightfully should be a part of the
+ * ISA code but it's easier to do it here for now), I/O port addresses,
+ * and I/O memory address space.
+ */
+
+#include "opt_smp.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/vmparam.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/pmap.h>
+
+#include <machine/ipl.h>
+#include <machine/resource.h>
+#ifdef APIC_IO
+#include <machine/smp.h>
+#include <machine/mpapic.h>
+#endif
+
+#include <i386/isa/isa.h>
+#include <i386/isa/icu.h>
+#include <i386/isa/intr_machdep.h>
+
+#include <pci/pcivar.h>
+
+#include "eisa.h"
+#include "isa.h"
+#include "pci.h"
+#include "npx.h"
+#include "apm.h"
+
+static struct rman irq_rman, drq_rman, port_rman, mem_rman;
+
+static int nexus_probe(device_t);
+static void nexus_print_child(device_t, device_t);
+static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+static int nexus_activate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_deactivate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_release_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_setup_intr(device_t, device_t, struct resource *,
+ void (*)(void *), void *, void **);
+static int nexus_teardown_intr(device_t, device_t, struct resource *,
+ void *);
+
+static device_method_t nexus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, nexus_print_child),
+ DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
+ DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
+ DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
+ DEVMETHOD(bus_release_resource, nexus_release_resource),
+ DEVMETHOD(bus_activate_resource, nexus_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, nexus_setup_intr),
+ DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t nexus_driver = {
+ "nexus",
+ nexus_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+static devclass_t nexus_devclass;
+
+DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
+
+#ifdef APIC_IO
+#define LASTIRQ (NINTR - 1)
+#else
+#define LASTIRQ 15
+#endif
+
+static int
+nexus_probe(device_t dev)
+{
+ device_t child;
+
+ device_quiet(dev); /* suppress attach message for neatness */
+
+ irq_rman.rm_start = 0;
+ irq_rman.rm_end = LASTIRQ;
+ irq_rman.rm_type = RMAN_ARRAY;
+ irq_rman.rm_descr = "Interrupt request lines";
+ if (rman_init(&irq_rman)
+ || rman_manage_region(&irq_rman, 0, 1)
+ || rman_manage_region(&irq_rman, 3, LASTIRQ))
+ panic("nexus_probe irq_rman");
+
+ drq_rman.rm_start = 0;
+ drq_rman.rm_end = 7;
+ drq_rman.rm_type = RMAN_ARRAY;
+ drq_rman.rm_descr = "DMA request lines";
+ /* XXX drq 0 not available on some machines */
+ if (rman_init(&drq_rman)
+ || rman_manage_region(&drq_rman, 0, 7))
+ panic("nexus_probe drq_rman");
+
+ port_rman.rm_start = 0;
+ port_rman.rm_end = 0xffff;
+ port_rman.rm_type = RMAN_ARRAY;
+ port_rman.rm_descr = "I/O ports";
+ if (rman_init(&port_rman)
+ || rman_manage_region(&port_rman, 0, 0xffff))
+ panic("nexus_probe port_rman");
+
+ mem_rman.rm_start = 0;
+ mem_rman.rm_end = ~0u;
+ mem_rman.rm_type = RMAN_ARRAY;
+ mem_rman.rm_descr = "I/O memory addresses";
+ if (rman_init(&mem_rman)
+ || rman_manage_region(&mem_rman, 0, ~0))
+ panic("nexus_probe mem_rman");
+
+#if NNPX > 0
+ child = device_add_child(dev, "npx", 0, 0);
+ if (child == 0)
+ panic("nexus_probe npx");
+#endif /* NNPX > 0 */
+#if NAPM > 0
+ child = device_add_child(dev, "apm", 0, 0);
+ if (child == 0)
+ panic("nexus_probe apm");
+#endif /* NAPM > 0 */
+#if NPCI > 0
+ /* Add a PCI bridge if pci bus is present */
+ if (pci_cfgopen() != 0) {
+ child = device_add_child(dev, "pcib", 0, 0);
+ if (child == 0)
+ panic("nexus_probe pcib");
+ }
+#endif
+#if 0 && NEISA > 0
+ child = device_add_child(dev, "eisa", 0, 0);
+ if (child == 0)
+ panic("nexus_probe eisa");
+#endif
+#if NISA > 0
+ /* Add an ISA bus directly if pci bus is not present */
+ if (pci_cfgopen() == 0) {
+ child = device_add_child(dev, "isa", 0, 0);
+ if (child == 0)
+ panic("nexus_probe isa");
+ }
+#endif
+ return 0;
+}
+
+static void
+nexus_print_child(device_t bus, device_t child)
+{
+ printf(" on motherboard");
+}
+
+/*
+ * Allocate a resource on behalf of child. NB: child is usually going to be a
+ * child of one of our descendants, not a direct child of nexus0.
+ * (Exceptions include npx.)
+ */
+static struct resource *
+nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct resource *rv;
+ struct rman *rm;
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ rm = &irq_rman;
+ break;
+
+ case SYS_RES_DRQ:
+ rm = &drq_rman;
+ break;
+
+ case SYS_RES_IOPORT:
+ rm = &port_rman;
+ break;
+
+ case SYS_RES_MEMORY:
+ rm = &mem_rman;
+ break;
+
+ default:
+ return 0;
+ }
+
+ rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (rv == 0)
+ return 0;
+
+ if (type == SYS_RES_MEMORY) {
+ caddr_t vaddr = 0;
+
+ if (rv->r_end < 1024 * 1024 * 1024) {
+ /*
+ * The first 1Mb is mapped at KERNBASE.
+ */
+ vaddr = (caddr_t)((uintptr_t)KERNBASE + rv->r_start);
+ } else {
+ u_int32_t paddr;
+ u_int32_t psize;
+ u_int32_t poffs;
+
+ paddr = rv->r_start;
+ psize = rv->r_end - rv->r_start;
+
+ poffs = paddr - trunc_page(paddr);
+ vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
+ }
+ rman_set_virtual(rv, vaddr);
+ rman_set_bustag(rv, I386_BUS_SPACE_MEM);
+ rman_set_bushandle(rv, (bus_space_handle_t) vaddr);
+ } else if (type == SYS_RES_IOPORT) {
+ rman_set_bustag(rv, I386_BUS_SPACE_IO);
+ rman_set_bushandle(rv, rv->r_start);
+ }
+ return rv;
+}
+
+static int
+nexus_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_activate_resource(r));
+}
+
+static int
+nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_deactivate_resource(r));
+}
+
+static int
+nexus_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_release_resource(r));
+}
+
+/*
+ * Currently this uses the really grody interface from kern/kern_intr.c
+ * (which really doesn't belong in kern/anything.c). Eventually, all of
+ * the code in kern_intr.c and machdep_intr.c should get moved here, since
+ * this is going to be the official interface.
+ */
+static int
+nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
+ void (*ihand)(void *), void *arg, void **cookiep)
+{
+ intrmask_t *mask;
+ driver_t *driver;
+ int error, icflags;
+
+ if (child)
+ device_printf(child, "interrupting at irq %d\n",
+ (int)irq->r_start);
+
+ *cookiep = 0;
+ if (irq->r_flags & RF_SHAREABLE)
+ icflags = 0;
+ else
+ icflags = INTR_EXCL;
+
+ driver = device_get_driver(child);
+ switch (driver->type) {
+ case DRIVER_TYPE_TTY:
+ mask = &tty_imask;
+ break;
+ case (DRIVER_TYPE_TTY | DRIVER_TYPE_FAST):
+ mask = &tty_imask;
+ icflags |= INTR_FAST;
+ break;
+ case DRIVER_TYPE_BIO:
+ mask = &bio_imask;
+ break;
+ case DRIVER_TYPE_NET:
+ mask = &net_imask;
+ break;
+ case DRIVER_TYPE_CAM:
+ mask = &cam_imask;
+ break;
+ case DRIVER_TYPE_MISC:
+ mask = 0;
+ break;
+ default:
+ panic("still using grody create_intr interface");
+ }
+
+ /*
+ * We depend here on rman_activate_resource() being idempotent.
+ */
+ error = rman_activate_resource(irq);
+ if (error)
+ return (error);
+
+ *cookiep = intr_create((void *)(intptr_t)-1, irq->r_start, ihand, arg,
+ mask, icflags);
+ if (*cookiep)
+ error = intr_connect(*cookiep);
+ else
+ error = EINVAL; /* XXX ??? */
+
+ return (error);
+}
+
+static int
+nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
+{
+ return (intr_destroy(ih));
+}
+
+static devclass_t pcib_devclass;
+
+static int
+nexus_pcib_probe(device_t dev)
+{
+ device_set_desc(dev, "PCI host bus adapter");
+
+ device_add_child(dev, "pci", 0, 0);
+
+ return 0;
+}
+
+static device_method_t nexus_pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_pcib_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t nexus_pcib_driver = {
+ "pcib",
+ nexus_pcib_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+DRIVER_MODULE(pcib, nexus, nexus_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 6ed3182..6980279 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.327 1999/03/06 04:46:18 wollman Exp $
+ * $Id: machdep.c,v 1.328 1999/04/03 22:19:58 jdp Exp $
*/
#include "apm.h"
@@ -71,6 +71,7 @@
#include <sys/sysent.h>
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
+#include <sys/bus.h>
#ifdef SYSVSHM
#include <sys/shm.h>
@@ -125,7 +126,9 @@
#include <machine/perfmon.h>
#endif
+#ifdef OLD_BUS_ARCH
#include <i386/isa/isa_device.h>
+#endif
#include <i386/isa/intr_machdep.h>
#ifndef VM86
#include <i386/isa/rtc.h>
@@ -1164,8 +1167,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;
@@ -1454,10 +1459,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/i386/i386/nexus.c b/sys/i386/i386/nexus.c
new file mode 100644
index 0000000..7df4387
--- /dev/null
+++ b/sys/i386/i386/nexus.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright 1998 Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+/*
+ * This code implements a `root nexus' for Intel Architecture
+ * machines. The function of the root nexus is to serve as an
+ * attachment point for both processors and buses, and to manage
+ * resources which are common to all of them. In particular,
+ * this code implements the core resource managers for interrupt
+ * requests, DMA requests (which rightfully should be a part of the
+ * ISA code but it's easier to do it here for now), I/O port addresses,
+ * and I/O memory address space.
+ */
+
+#include "opt_smp.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/vmparam.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <machine/pmap.h>
+
+#include <machine/ipl.h>
+#include <machine/resource.h>
+#ifdef APIC_IO
+#include <machine/smp.h>
+#include <machine/mpapic.h>
+#endif
+
+#include <i386/isa/isa.h>
+#include <i386/isa/icu.h>
+#include <i386/isa/intr_machdep.h>
+
+#include <pci/pcivar.h>
+
+#include "eisa.h"
+#include "isa.h"
+#include "pci.h"
+#include "npx.h"
+#include "apm.h"
+
+static struct rman irq_rman, drq_rman, port_rman, mem_rman;
+
+static int nexus_probe(device_t);
+static void nexus_print_child(device_t, device_t);
+static struct resource *nexus_alloc_resource(device_t, device_t, int, int *,
+ u_long, u_long, u_long, u_int);
+static int nexus_activate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_deactivate_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_release_resource(device_t, device_t, int, int,
+ struct resource *);
+static int nexus_setup_intr(device_t, device_t, struct resource *,
+ void (*)(void *), void *, void **);
+static int nexus_teardown_intr(device_t, device_t, struct resource *,
+ void *);
+
+static device_method_t nexus_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_detach, bus_generic_detach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, nexus_print_child),
+ DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
+ DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
+ DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
+ DEVMETHOD(bus_release_resource, nexus_release_resource),
+ DEVMETHOD(bus_activate_resource, nexus_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, nexus_setup_intr),
+ DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t nexus_driver = {
+ "nexus",
+ nexus_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+static devclass_t nexus_devclass;
+
+DRIVER_MODULE(nexus, root, nexus_driver, nexus_devclass, 0, 0);
+
+#ifdef APIC_IO
+#define LASTIRQ (NINTR - 1)
+#else
+#define LASTIRQ 15
+#endif
+
+static int
+nexus_probe(device_t dev)
+{
+ device_t child;
+
+ device_quiet(dev); /* suppress attach message for neatness */
+
+ irq_rman.rm_start = 0;
+ irq_rman.rm_end = LASTIRQ;
+ irq_rman.rm_type = RMAN_ARRAY;
+ irq_rman.rm_descr = "Interrupt request lines";
+ if (rman_init(&irq_rman)
+ || rman_manage_region(&irq_rman, 0, 1)
+ || rman_manage_region(&irq_rman, 3, LASTIRQ))
+ panic("nexus_probe irq_rman");
+
+ drq_rman.rm_start = 0;
+ drq_rman.rm_end = 7;
+ drq_rman.rm_type = RMAN_ARRAY;
+ drq_rman.rm_descr = "DMA request lines";
+ /* XXX drq 0 not available on some machines */
+ if (rman_init(&drq_rman)
+ || rman_manage_region(&drq_rman, 0, 7))
+ panic("nexus_probe drq_rman");
+
+ port_rman.rm_start = 0;
+ port_rman.rm_end = 0xffff;
+ port_rman.rm_type = RMAN_ARRAY;
+ port_rman.rm_descr = "I/O ports";
+ if (rman_init(&port_rman)
+ || rman_manage_region(&port_rman, 0, 0xffff))
+ panic("nexus_probe port_rman");
+
+ mem_rman.rm_start = 0;
+ mem_rman.rm_end = ~0u;
+ mem_rman.rm_type = RMAN_ARRAY;
+ mem_rman.rm_descr = "I/O memory addresses";
+ if (rman_init(&mem_rman)
+ || rman_manage_region(&mem_rman, 0, ~0))
+ panic("nexus_probe mem_rman");
+
+#if NNPX > 0
+ child = device_add_child(dev, "npx", 0, 0);
+ if (child == 0)
+ panic("nexus_probe npx");
+#endif /* NNPX > 0 */
+#if NAPM > 0
+ child = device_add_child(dev, "apm", 0, 0);
+ if (child == 0)
+ panic("nexus_probe apm");
+#endif /* NAPM > 0 */
+#if NPCI > 0
+ /* Add a PCI bridge if pci bus is present */
+ if (pci_cfgopen() != 0) {
+ child = device_add_child(dev, "pcib", 0, 0);
+ if (child == 0)
+ panic("nexus_probe pcib");
+ }
+#endif
+#if 0 && NEISA > 0
+ child = device_add_child(dev, "eisa", 0, 0);
+ if (child == 0)
+ panic("nexus_probe eisa");
+#endif
+#if NISA > 0
+ /* Add an ISA bus directly if pci bus is not present */
+ if (pci_cfgopen() == 0) {
+ child = device_add_child(dev, "isa", 0, 0);
+ if (child == 0)
+ panic("nexus_probe isa");
+ }
+#endif
+ return 0;
+}
+
+static void
+nexus_print_child(device_t bus, device_t child)
+{
+ printf(" on motherboard");
+}
+
+/*
+ * Allocate a resource on behalf of child. NB: child is usually going to be a
+ * child of one of our descendants, not a direct child of nexus0.
+ * (Exceptions include npx.)
+ */
+static struct resource *
+nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct resource *rv;
+ struct rman *rm;
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ rm = &irq_rman;
+ break;
+
+ case SYS_RES_DRQ:
+ rm = &drq_rman;
+ break;
+
+ case SYS_RES_IOPORT:
+ rm = &port_rman;
+ break;
+
+ case SYS_RES_MEMORY:
+ rm = &mem_rman;
+ break;
+
+ default:
+ return 0;
+ }
+
+ rv = rman_reserve_resource(rm, start, end, count, flags, child);
+ if (rv == 0)
+ return 0;
+
+ if (type == SYS_RES_MEMORY) {
+ caddr_t vaddr = 0;
+
+ if (rv->r_end < 1024 * 1024 * 1024) {
+ /*
+ * The first 1Mb is mapped at KERNBASE.
+ */
+ vaddr = (caddr_t)((uintptr_t)KERNBASE + rv->r_start);
+ } else {
+ u_int32_t paddr;
+ u_int32_t psize;
+ u_int32_t poffs;
+
+ paddr = rv->r_start;
+ psize = rv->r_end - rv->r_start;
+
+ poffs = paddr - trunc_page(paddr);
+ vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
+ }
+ rman_set_virtual(rv, vaddr);
+ rman_set_bustag(rv, I386_BUS_SPACE_MEM);
+ rman_set_bushandle(rv, (bus_space_handle_t) vaddr);
+ } else if (type == SYS_RES_IOPORT) {
+ rman_set_bustag(rv, I386_BUS_SPACE_IO);
+ rman_set_bushandle(rv, rv->r_start);
+ }
+ return rv;
+}
+
+static int
+nexus_activate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_activate_resource(r));
+}
+
+static int
+nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_deactivate_resource(r));
+}
+
+static int
+nexus_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+ return (rman_release_resource(r));
+}
+
+/*
+ * Currently this uses the really grody interface from kern/kern_intr.c
+ * (which really doesn't belong in kern/anything.c). Eventually, all of
+ * the code in kern_intr.c and machdep_intr.c should get moved here, since
+ * this is going to be the official interface.
+ */
+static int
+nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
+ void (*ihand)(void *), void *arg, void **cookiep)
+{
+ intrmask_t *mask;
+ driver_t *driver;
+ int error, icflags;
+
+ if (child)
+ device_printf(child, "interrupting at irq %d\n",
+ (int)irq->r_start);
+
+ *cookiep = 0;
+ if (irq->r_flags & RF_SHAREABLE)
+ icflags = 0;
+ else
+ icflags = INTR_EXCL;
+
+ driver = device_get_driver(child);
+ switch (driver->type) {
+ case DRIVER_TYPE_TTY:
+ mask = &tty_imask;
+ break;
+ case (DRIVER_TYPE_TTY | DRIVER_TYPE_FAST):
+ mask = &tty_imask;
+ icflags |= INTR_FAST;
+ break;
+ case DRIVER_TYPE_BIO:
+ mask = &bio_imask;
+ break;
+ case DRIVER_TYPE_NET:
+ mask = &net_imask;
+ break;
+ case DRIVER_TYPE_CAM:
+ mask = &cam_imask;
+ break;
+ case DRIVER_TYPE_MISC:
+ mask = 0;
+ break;
+ default:
+ panic("still using grody create_intr interface");
+ }
+
+ /*
+ * We depend here on rman_activate_resource() being idempotent.
+ */
+ error = rman_activate_resource(irq);
+ if (error)
+ return (error);
+
+ *cookiep = intr_create((void *)(intptr_t)-1, irq->r_start, ihand, arg,
+ mask, icflags);
+ if (*cookiep)
+ error = intr_connect(*cookiep);
+ else
+ error = EINVAL; /* XXX ??? */
+
+ return (error);
+}
+
+static int
+nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
+{
+ return (intr_destroy(ih));
+}
+
+static devclass_t pcib_devclass;
+
+static int
+nexus_pcib_probe(device_t dev)
+{
+ device_set_desc(dev, "PCI host bus adapter");
+
+ device_add_child(dev, "pci", 0, 0);
+
+ return 0;
+}
+
+static device_method_t nexus_pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, nexus_pcib_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t nexus_pcib_driver = {
+ "pcib",
+ nexus_pcib_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+DRIVER_MODULE(pcib, nexus, nexus_pcib_driver, pcib_devclass, 0, 0);
diff --git a/sys/i386/i386/userconfig.c b/sys/i386/i386/userconfig.c
index 5c557a7..751c7b8 100644
--- a/sys/i386/i386/userconfig.c
+++ b/sys/i386/i386/userconfig.c
@@ -46,7 +46,7 @@
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
- ** $Id: userconfig.c,v 1.132 1999/02/21 16:33:51 n_hibma Exp $
+ ** $Id: userconfig.c,v 1.133 1999/04/06 17:08:30 wpaul Exp $
**/
/**
@@ -115,11 +115,13 @@
#include <sys/reboot.h>
#include <sys/linker.h>
#include <sys/sysctl.h>
+#include <sys/bus.h>
#include <machine/cons.h>
#include <machine/md_var.h>
#include <machine/limits.h>
+
#include <i386/isa/isa_device.h>
#include "pnp.h"
@@ -132,11 +134,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
{
@@ -279,8 +287,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
{
@@ -538,12 +544,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 */
@@ -563,7 +567,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++)
{
@@ -847,6 +850,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;
}
@@ -855,6 +859,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 */
}
@@ -2510,7 +2515,7 @@ visuserconfig(void)
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: userconfig.c,v 1.132 1999/02/21 16:33:51 n_hibma Exp $
+ * $Id: userconfig.c,v 1.133 1999/04/06 17:08:30 wpaul Exp $
*/
#include "scbus.h"
@@ -2659,6 +2664,7 @@ userconfig(void)
int rval;
Cmd *cmd;
+ load_devtab();
init_config_script();
while (1) {
@@ -2693,8 +2699,10 @@ userconfig(void)
continue;
}
rval = (*cmd->handler)(cmd->parms);
- if (rval)
+ if (rval) {
+ free_devtab();
return;
+ }
}
}
@@ -2792,11 +2800,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
@@ -3312,20 +3316,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;
}
@@ -3532,6 +3581,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;
@@ -3544,6 +3616,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/i386/include/asnames.h b/sys/i386/include/asnames.h
index b1d8a08..8ac432c 100644
--- a/sys/i386/include/asnames.h
+++ b/sys/i386/include/asnames.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: asnames.h,v 1.29 1999/02/22 15:13:34 bde Exp $
+ * $Id: asnames.h,v 1.30 1999/02/25 12:53:34 bde Exp $
*/
#ifndef _MACHINE_ASNAMES_H_
@@ -291,7 +291,7 @@
#define _normalize_nuo normalize_nuo
#define _npx_intrs_while_probing npx_intrs_while_probing
#define _npx_traps_while_probing npx_traps_while_probing
-#define _npxintr npxintr
+#define _npx_intr npx_intr
#define _npxproc npxproc
#define _npxsave npxsave
#define _other_cpus other_cpus
diff --git a/sys/i386/isa/aha_isa.c b/sys/i386/isa/aha_isa.c
index 9426679..c3704df 100644
--- a/sys/i386/isa/aha_isa.c
+++ b/sys/i386/isa/aha_isa.c
@@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aha_isa.c,v 1.5 1998/11/10 06:44:54 gibbs Exp $
+ * $Id: aha_isa.c,v 1.6 1999/01/20 06:21:23 imp Exp $
*/
#include "pnp.h"
@@ -257,7 +257,6 @@ static void
ahapnp_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 >= NAHATOT)
return;
@@ -278,9 +277,7 @@ ahapnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev)
if (dev->id_driver == NULL) {
dev->id_driver = &ahadriver;
- dvp = find_isadev(isa_devtab_tty, &ahadriver, 0);
- if (dvp != NULL)
- dev->id_id = dvp->id_id;
+ dev->id_id = isa_compat_nextid();
}
if ((dev->id_alive = aha_isa_probe(dev)) != 0)
diff --git a/sys/i386/isa/fd.c b/sys/i386/isa/fd.c
index 07223f1..0414b18 100644
--- a/sys/i386/isa/fd.c
+++ b/sys/i386/isa/fd.c
@@ -47,7 +47,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.133 1999/02/10 00:03:32 ken Exp $
+ * $Id: fd.c,v 1.134 1999/04/06 03:06:51 peter Exp $
*
*/
@@ -60,26 +60,37 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <machine/clock.h>
-#include <machine/ioctl_fd.h>
#include <sys/disklabel.h>
-#include <sys/buf.h>
#include <sys/devicestat.h>
+#include <sys/fcntl.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/proc.h>
#include <sys/syslog.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/fdreg.h>
-#include <i386/isa/fdc.h>
-#include <i386/isa/rtc.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/clock.h>
+#include <machine/ioctl_fd.h>
+#include <machine/resource.h>
#include <machine/stdarg.h>
+
#ifdef DEVFS
#include <sys/devfsext.h>
#endif /* DEVFS */
+#include <isa/isavar.h>
+#include <i386/isa/isa.h>
+#include <i386/isa/isa_dma.h>
+#include <i386/isa/fdreg.h>
+#include <i386/isa/fdc.h>
+#include <i386/isa/rtc.h>
+
/* misuse a flag to identify format operation */
#define B_FORMAT B_XXX
@@ -151,13 +162,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...) */
@@ -179,7 +190,10 @@ static struct fd_data {
void *bdevs[1 + NUMDENS + MAXPARTITIONS];
void *cdevs[1 + NUMDENS + MAXPARTITIONS];
#endif
-} fd_data[NFD];
+ device_t dev;
+ fdu_t fdu;
+};
+static devclass_t fd_devclass;
/***********************************************************************\
* Throughout this file the following conventions will be used: *
@@ -195,29 +209,26 @@ static struct fd_data {
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);
@@ -356,13 +367,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;
@@ -374,28 +378,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;
@@ -407,9 +401,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;
@@ -422,26 +415,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);
}
}
@@ -462,8 +455,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;
@@ -474,17 +467,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;
}
@@ -493,9 +486,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;
@@ -506,13 +499,11 @@ 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;
- 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;
}
@@ -520,17 +511,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)
@@ -545,8 +534,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
@@ -554,7 +542,7 @@ fd_read_status(fdc_p fdc, int fdsu)
*/
int status;
- ret = fd_in(fdc->fdcu, &status);
+ ret = fd_in(fdc, &status);
fdc->status[i] = status;
if (ret != 0)
break;
@@ -572,34 +560,92 @@ fd_read_status(fdc_p fdc, int fdsu)
/* autoconfiguration stuff */
/****************************************************************************/
-/*
- * 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);
/* 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);
/* see if it can handle a command */
- if (fd_cmd(fdcu,
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
- 0))
- {
- return(0);
+ if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
+ NE7_SPEC_2(2, 0), 0)) {
+ error = ENXIO;
+ goto out;
+ }
+
+ 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;
+ }
}
+
+ 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
@@ -608,277 +654,312 @@ 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;
- int fdsu, st0, st3, i;
- struct isa_device *fdup;
- int ic_type = 0;
-#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;
- fdc->dmachan = dev->id_drq;
+
/* 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;
+
/* reset controller, turn motor off, clear fdout mirror reg */
outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
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) {
- 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;
- }
- /* is there a unit? */
- if ((fdt == RTCFDT_NONE)
- ) {
- fd->type = NO_TYPE;
- continue;
- }
+#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));
+}
- /* select it */
- set_motor(fdcu, fdsu, TURNON);
- DELAY(1000000); /* 1 sec */
+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));
+}
- 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");
+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
- fdc->fdct = FDC_NE72065;
- break;
- default:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("unknown IC type %02x\n", ic_type);
+
+ 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);
+
+ /* 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;
+ }
+
+ /* is there a unit? */
+ if (fdt == RTCFDT_NONE)
+ return (ENXIO);
+
+ /* 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);
- 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) {
- case RTCFDT_12M:
- printf("1.2MB 5.25in\n");
- fd->type = FD_1200;
- 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;
+ fd->track = FD_NO_TRACK;
+ fd->fdc = fdc;
+ fd->fdsu = fdsu;
+ fd->options = 0;
+ callout_handle_init(&fd->toffhandle);
+ callout_handle_init(&fd->tohandle);
+
+ 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);
+ }
+ return (0);
+}
+
+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.
+ */
+ switch (fd->type) {
+ case FD_360:
+ if (i != FD_360)
+ continue;
break;
- case RTCFDT_288M:
- case RTCFDT_288M_1:
- printf("2.88MB 3.5in - 1.44MB mode\n");
- fd->type = FD_1440;
+ case FD_720:
+ if (i != FD_720 && i != FD_800 && i != FD_820)
+ continue;
break;
- case RTCFDT_360K:
- printf("360KB 5.25in\n");
- fd->type = FD_360;
+ 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_720K:
- printf("720KB 3.5in\n");
- fd->type = FD_720;
+ 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;
- 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.
- */
- 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;
- }
- 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;
- 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 */
+ 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;
+ 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
@@ -1016,9 +1097,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;
if(turnon) {
@@ -1038,83 +1119,78 @@ set_motor(fdcu_t fdcu, int fdsu, int turnon)
fdout |= (FDO_FRST|FDO_FDMAEN);
}
- outb(fdc_data[fdcu].baseport+FDOUT, fdout);
- 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
* from its sleep, we silently assume the command will
* be accepted, and do not test for a timeout
*/
- (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);
- 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 */
outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
@@ -1127,7 +1203,7 @@ fdc_reset(fdc_p fdc)
TRACE1("[0x%x->FDOUT]", fdc->fdout);
/* XXX after a reset, silently believe the FDC will accept commands */
- (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);
if (fdc->flags & FDC_HAS_FIFO)
@@ -1138,16 +1214,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);
@@ -1161,16 +1237,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);
@@ -1185,21 +1261,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);
@@ -1215,32 +1291,33 @@ 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);
if (type == 0)
- type = fd_data[fdu].type;
+ type = fd->type;
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) {
@@ -1279,9 +1356,10 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
}
}
}
- 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;
}
@@ -1289,11 +1367,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
@@ -1317,16 +1397,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;
@@ -1341,7 +1422,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);
@@ -1386,12 +1467,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;
@@ -1409,27 +1490,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);
/*
@@ -1447,19 +1526,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);
}
@@ -1469,11 +1547,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
@@ -1513,7 +1591,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;
@@ -1537,26 +1615,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;
@@ -1569,8 +1646,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:
@@ -1585,10 +1662,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 *
@@ -1596,12 +1672,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);
}
if (fdc->flags & FDC_NEEDS_RESET) {
fdc->state = RESETCTLR;
@@ -1615,7 +1691,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdc->state = SEEKCOMPLETE;
break;
}
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK,
+ if (fd_cmd(fdc, 3, NE7CMD_SEEK,
fd->fdsu, b_cylinder * fd->ft->steptrac,
0))
{
@@ -1624,20 +1700,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 {
/*
@@ -1669,8 +1744,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
@@ -1685,22 +1759,20 @@ 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));
}
}
- 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));
}
}
@@ -1726,7 +1798,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)
{
@@ -1749,8 +1821,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,
@@ -1758,25 +1829,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) {
/*
@@ -1795,7 +1860,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 */
@@ -1805,14 +1870,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
@@ -1834,8 +1898,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 FDC_YE
case PIOREAD:
/*
@@ -1847,16 +1911,15 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
/* FALLTHROUGH */
#endif
case IOCOMPLETE: /* IO DONE, post-analyze */
- untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle);
+ untimeout(fd_iotimeout, fdc, fd->tohandle);
- 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;
@@ -1869,8 +1932,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
#endif
isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
format ? bp->b_bcount : fdblk, fdc->dmachan);
- 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) {
/*
@@ -1890,17 +1952,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;
@@ -1915,7 +1974,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++;
@@ -1931,21 +1990,18 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdc->state = STARTRECAL;
/* Fall through. */
case STARTRECAL:
- 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 {
/*
@@ -1971,16 +2027,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;
@@ -1993,9 +2049,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],
@@ -2010,28 +2067,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;
@@ -2084,10 +2144,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
@@ -2104,7 +2164,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() */
@@ -2135,20 +2195,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
@@ -2171,7 +2230,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;
@@ -2181,13 +2240,12 @@ fdioctl(dev, cmd, addr, flag, p)
fdblk = 128 << fd->ft->secsize;
- 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;
@@ -2211,8 +2269,7 @@ fdioctl(dev, cmd, addr, flag, p)
break;
case DIOCWDINFO:
- if ((flag & FWRITE) == 0)
- {
+ if ((flag & FWRITE) == 0) {
error = EBADF;
break;
}
@@ -2227,9 +2284,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
@@ -2242,7 +2299,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;
@@ -2262,22 +2319,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/i386/isa/fdc.h b/sys/i386/isa/fdc.h
index 43bf9f8..83e291f 100644
--- a/sys/i386/isa/fdc.h
+++ b/sys/i386/isa/fdc.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fdc.h,v 1.12 1998/12/12 08:16:01 imp Exp $
+ * $Id: fdc.h,v 1.13 1999/01/15 09:15:27 bde Exp $
*
*/
@@ -70,6 +70,10 @@ struct fdc_data
int fdc_errs; /* number of logged errors */
struct buf_queue_head head;
struct buf *bp; /* active buffer */
+ struct resource *res_ioport, *res_irq, *res_drq;
+ int rid_ioport, rid_irq, rid_drq;
+ void *fdc_intr;
+ struct device *fdc_dev;
};
/***********************************************************************\
diff --git a/sys/i386/isa/if_cs.c b/sys/i386/isa/if_cs.c
index 4a9c390..f96f024 100644
--- a/sys/i386/isa/if_cs.c
+++ b/sys/i386/isa/if_cs.c
@@ -27,7 +27,7 @@
*/
/*
- * $Id: if_cs.c,v 1.8 1999/01/12 00:27:43 eivind Exp $
+ * $Id: if_cs.c,v 1.9 1999/01/28 01:59:53 dillon Exp $
*
* Device driver for Crystal Semiconductor CS8920 based ethernet
* adapters. By Maxim Bolotin and Oleg Sharoiko, 27-April-1997
@@ -1352,7 +1352,6 @@ cs_pnp_attach(u_long csn, u_long vend_id, char *name,
int iobase, unit, flags;
u_int irq;
int drq;
- struct isa_device *dvp;
struct cs_softc *sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT);
if (read_pnp_parms ( &d , ldn ) == 0 ) {
@@ -1373,9 +1372,7 @@ cs_pnp_attach(u_long csn, u_long vend_id, char *name,
if (dev->id_driver == NULL) {
dev->id_driver = &csdriver;
- dvp = find_isadev(isa_devtab_net, &csdriver, 0);
- if (dvp != NULL)
- dev->id_id = dvp->id_id;
+ dev->id_id = isa_compat_nextid();
}
if (!sc) return;
diff --git a/sys/i386/isa/if_ed.c b/sys/i386/isa/if_ed.c
index 1408b2b..29bb9d1 100644
--- a/sys/i386/isa/if_ed.c
+++ b/sys/i386/isa/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.149 1999/01/28 01:59:53 dillon Exp $
+ * $Id: if_ed.c,v 1.150 1999/03/17 16:44:51 luigi Exp $
*/
/*
@@ -3488,7 +3488,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;
@@ -3509,9 +3508,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/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c
index 944eb4e..4f7c1e9 100644
--- a/sys/i386/isa/intr_machdep.c
+++ b/sys/i386/isa/intr_machdep.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id: intr_machdep.c,v 1.16 1999/01/08 19:17:48 bde Exp $
+ * $Id: intr_machdep.c,v 1.17 1999/04/14 14:26:36 bde Exp $
*/
#include "opt_auto_eoi.h"
@@ -328,6 +328,7 @@ isa_get_nameunit(int id)
return ("clk0"); /* XXX may also be sloppy driver */
if (id == 1)
return ("rtc0");
+#if 0
for (dp = isa_devtab_bio; dp->id_driver != NULL; dp++)
if (dp->id_id == id)
goto found_device;
@@ -343,6 +344,7 @@ isa_get_nameunit(int id)
for (dp = isa_devtab_tty; dp->id_driver != NULL; dp++)
if (dp->id_id == id)
goto found_device;
+#endif
return "???";
found_device:
diff --git a/sys/i386/isa/isa.c b/sys/i386/isa/isa.c
index 1e91da8..4b48e36 100644
--- a/sys/i386/isa/isa.c
+++ b/sys/i386/isa/isa.c
@@ -1,10 +1,7 @@
/*-
- * Copyright (c) 1991 The Regents of the University of California.
+ * Copyright (c) 1998 Doug Rabson
* 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:
@@ -13,18 +10,11 @@
* 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
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -33,1041 +23,601 @@
* 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.c,v 1.117 1998/11/29 15:42:40 phk Exp $
+ * $Id: isa.c,v 1.4 1998/09/16 08:23:51 dfr Exp $
*/
/*
- * code to manage AT bus
+ * Modifications for Intel architecture by Garrett A. Wollman.
+ * Copyright 1998 Massachusetts Institute of Technology
*
- * 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()
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that both the above copyright notice and this
+ * permission notice appear in all copies, that both the above
+ * copyright notice and this permission notice appear in all
+ * supporting documentation, and that the name of M.I.T. not be used
+ * in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. M.I.T. makes
+ * no representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied
+ * warranty.
+ *
+ * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
+ * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
+ * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/buf.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
#include <sys/malloc.h>
-#include <machine/ipl.h>
-#include <machine/md_var.h>
-#ifdef APIC_IO
-#include <machine/smp.h>
-#endif /* APIC_IO */
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/intr_machdep.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/ic/i8237.h>
-
-#include <sys/interrupt.h>
-
-#include "pnp.h"
-#if NPNP > 0
-#include <i386/isa/pnp.h>
-#endif
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
-/*
-** Register definitions for DMA controller 1 (channels 0..3):
-*/
-#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 */
+#include <machine/resource.h>
-/*
-** 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 */
+#include <isa/isavar.h>
-static void config_isadev __P((struct isa_device *isdp, u_int *mp));
-static void config_isadev_c __P((struct isa_device *isdp, u_int *mp,
- int reconfig));
-static void conflict __P((struct isa_device *dvp, struct isa_device *tmpdvp,
- int item, char const *whatnot, char const *reason,
- char const *format));
-static int haveseen __P((struct isa_device *dvp, struct isa_device *tmpdvp,
- u_int checkbits));
-static int isa_dmarangecheck __P((caddr_t va, u_int length, int chan));
+MALLOC_DEFINE(M_ISADEV, "isadev", "ISA device");
/*
- * print a conflict message
+ * The structure used to attach devices to the isa bus.
*/
+struct isa_device {
+ short id_port[ISA_NPORT_IVARS];
+ u_short id_portsize[ISA_NPORT_IVARS];
+ vm_offset_t id_maddr[ISA_NMEM_IVARS];
+ vm_size_t id_msize[ISA_NMEM_IVARS];
+ int id_irq[ISA_NIRQ_IVARS];
+ int id_drq[ISA_NDRQ_IVARS];
+ int id_flags;
+ struct resource *id_portres[ISA_NPORT_IVARS];
+ struct resource *id_memres[ISA_NMEM_IVARS];
+ struct resource *id_irqres[ISA_NIRQ_IVARS];
+ struct resource *id_drqres[ISA_NDRQ_IVARS];
+};
+
+#define DEVTOISA(dev) ((struct isa_device *) device_get_ivars(dev))
+
+static devclass_t isa_devclass;
+
static void
-conflict(dvp, tmpdvp, item, whatnot, reason, format)
- struct isa_device *dvp;
- struct isa_device *tmpdvp;
- int item;
- char const *whatnot;
- char const *reason;
- char const *format;
+isa_add_device(device_t dev, const char *name, int unit)
{
- printf("%s%d not %sed due to %s conflict with %s%d at ",
- dvp->id_driver->name, dvp->id_unit, whatnot, reason,
- tmpdvp->id_driver->name, tmpdvp->id_unit);
- printf(format, item);
- printf("\n");
-}
+ struct isa_device *idev;
+ device_t child;
+ int sensitive, t;
+ static device_t last_sensitive;
-/*
- * Check to see if things are already in use, like IRQ's, I/O addresses
- * and Memory addresses.
- */
-static int
-haveseen(dvp, tmpdvp, checkbits)
- struct isa_device *dvp;
- struct isa_device *tmpdvp;
- u_int checkbits;
-{
- /*
- * Ignore all conflicts except IRQ ones if conflicts are allowed.
- */
- if (dvp->id_conflicts)
- checkbits &= ~(CC_DRQ | CC_IOADDR | CC_MEMADDR);
- /*
- * Only check against devices that have already been found.
- */
- if (tmpdvp->id_alive) {
- char const *whatnot;
+ if (resource_int_value(name, unit, "sensitive", &sensitive) != 0)
+ sensitive = 0;
- /*
- * Check for device driver & unit conflict; just drop probing
- * a device which has already probed true. This is usually
- * not strictly a conflict, but rather the case of somebody
- * having specified several mutually exclusive configurations
- * for a single device.
- */
- if (tmpdvp->id_driver == dvp->id_driver &&
- tmpdvp->id_unit == dvp->id_unit) {
- return 1;
- }
+ idev = malloc(sizeof(struct isa_device), M_ISADEV, M_NOWAIT);
+ if (!idev)
+ return;
+ bzero(idev, sizeof *idev);
- whatnot = checkbits & CC_ATTACH ? "attach" : "prob";
- /*
- * Check for I/O address conflict. We can only check the
- * starting address of the device against the range of the
- * device that has already been probed since we do not
- * know how many I/O addresses this device uses.
- */
- if (checkbits & CC_IOADDR && tmpdvp->id_alive != -1) {
- if ((dvp->id_iobase >= tmpdvp->id_iobase) &&
- (dvp->id_iobase <=
- (tmpdvp->id_iobase + tmpdvp->id_alive - 1))) {
- if (!(checkbits & CC_QUIET))
- conflict(dvp, tmpdvp, dvp->id_iobase,
- whatnot, "I/O address", "0x%x");
- return 1;
- }
- }
- /*
- * Check for Memory address conflict. We can check for
- * range overlap, but it will not catch all cases since the
- * driver may adjust the msize paramater during probe, for
- * now we just check that the starting address does not
- * fall within any allocated region.
- * XXX could add a second check after the probe for overlap,
- * since at that time we would know the full range.
- * XXX KERNBASE is a hack, we should have vaddr in the table!
- */
- if (checkbits & CC_MEMADDR && tmpdvp->id_maddr) {
- if ((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) &&
- (KERNBASE + dvp->id_maddr <=
- (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) {
- if (!(checkbits & CC_QUIET))
- conflict(dvp, tmpdvp,
- (int)dvp->id_maddr, whatnot,
- "maddr", "0x%x");
- return 1;
- }
- }
- /*
- * Check for IRQ conflicts.
- */
- if (checkbits & CC_IRQ && tmpdvp->id_irq) {
- if (tmpdvp->id_irq == dvp->id_irq) {
- if (!(checkbits & CC_QUIET))
- conflict(dvp, tmpdvp,
- ffs(dvp->id_irq) - 1, whatnot,
- "irq", "%d");
- return 1;
- }
- }
- /*
- * Check for DRQ conflicts.
- */
- if (checkbits & CC_DRQ && tmpdvp->id_drq != -1) {
- if (tmpdvp->id_drq == dvp->id_drq) {
- if (!(checkbits & CC_QUIET))
- conflict(dvp, tmpdvp, dvp->id_drq,
- whatnot, "drq", "%d");
- return 1;
- }
- }
- }
- return 0;
-}
+ if (resource_int_value(name, unit, "port", &t) == 0)
+ idev->id_port[0] = t;
+ else
+ idev->id_port[0] = -1;
+ idev->id_port[1] = 0;
-#ifdef RESOURCE_CHECK
-#include <sys/drvresource.h>
+ if (resource_int_value(name, unit, "portsize", &t) == 0)
+ idev->id_portsize[0] = t;
+ else
+ idev->id_portsize[0] = 0;
+ idev->id_portsize[1] = 0;
-static int
-checkone (struct isa_device *dvp, int type, addr_t low, addr_t high,
- char *resname, char *resfmt, int attaching)
-{
- int result = 0;
- if (bootverbose) {
- if (low == high)
- printf("\tcheck %s: 0x%x\n", resname, low);
- else
- printf("\tcheck %s: 0x%x to 0x%x\n",
- resname, low, high);
- }
- if (resource_check(type, RESF_NONE, low, high) != NULL) {
- char *whatnot = attaching ? "attach" : "prob";
- static struct isa_device dummydev;
- static struct isa_driver dummydrv;
- struct isa_device *tmpdvp = &dummydev;
+ if (resource_int_value(name, unit, "maddr", &t) == 0)
+ idev->id_maddr[0] = t;
+ else
+ idev->id_maddr[0] = 0;
+ idev->id_maddr[1] = 0;
- dummydev.id_driver = &dummydrv;
- dummydev.id_unit = 0;
- dummydrv.name = "pci";
- conflict(dvp, tmpdvp, low, whatnot, resname, resfmt);
- result = 1;
- } else if (attaching) {
- if (low == high)
- printf("\tregister %s: 0x%x\n", resname, low);
- else
- printf("\tregister %s: 0x%x to 0x%x\n",
- resname, low, high);
- resource_claim(dvp, type, RESF_NONE, low, high);
- }
- return (result);
-}
+ if (resource_int_value(name, unit, "msize", &t) == 0)
+ idev->id_msize[0] = t;
+ else
+ idev->id_msize[0] = 0;
+ idev->id_msize[1] = 0;
-static int
-check_pciconflict(struct isa_device *dvp, int checkbits)
-{
- int result = 0;
- int attaching = (checkbits & CC_ATTACH) != 0;
+ if (resource_int_value(name, unit, "flags", &t) == 0)
+ idev->id_flags = t;
+ else
+ idev->id_flags = 0;
- if (checkbits & CC_MEMADDR) {
- long maddr = dvp->id_maddr;
- long msize = dvp->id_msize;
- if (msize > 0) {
- if (checkone(dvp, REST_MEM, maddr, maddr + msize - 1,
- "maddr", "0x%x", attaching) != 0) {
- result = 1;
- attaching = 0;
- }
- }
- }
- if (checkbits & CC_IOADDR) {
- unsigned iobase = dvp->id_iobase;
- unsigned iosize = dvp->id_alive;
- if (iosize == -1)
- iosize = 1; /* XXX can't do much about this ... */
- if (iosize > 0) {
- if (checkone(dvp, REST_PORT, iobase, iobase + iosize -1,
- "I/O address", "0x%x", attaching) != 0) {
- result = 1;
- attaching = 0;
- }
- }
- }
- if (checkbits & CC_IRQ) {
- int irq = ffs(dvp->id_irq) - 1;
- if (irq >= 0) {
- if (checkone(dvp, REST_INT, irq, irq,
- "irq", "%d", attaching) != 0) {
- result = 1;
- attaching = 0;
- }
- }
- }
- if (checkbits & CC_DRQ) {
- int drq = dvp->id_drq;
- if (drq >= 0) {
- if (checkone(dvp, REST_DMA, drq, drq,
- "drq", "%d", attaching) != 0) {
- result = 1;
- attaching = 0;
- }
- }
- }
- if (result != 0)
- resource_free (dvp);
- return (result);
-}
-#endif /* RESOURCE_CHECK */
+ if (resource_int_value(name, unit, "irq", &t) == 0)
+ idev->id_irq[0] = t;
+ else
+ idev->id_irq[0] = -1;
+ idev->id_irq[1] = -1;
-/*
- * Search through all the isa_devtab_* tables looking for anything that
- * conflicts with the current device.
- */
-int
-haveseen_isadev(dvp, checkbits)
- struct isa_device *dvp;
- u_int checkbits;
-{
-#if NPNP > 0
- struct pnp_dlist_node *nod;
-#endif
- struct isa_device *tmpdvp;
- int status = 0;
+ if (resource_int_value(name, unit, "drq", &t) == 0)
+ idev->id_drq[0] = t;
+ else
+ idev->id_drq[0] = -1;
+ idev->id_drq[1] = -1;
- for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
- for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
- for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
- for (tmpdvp = isa_devtab_cam; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
- for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++) {
- status |= haveseen(dvp, tmpdvp, checkbits);
- if (status)
- return status;
- }
-#if NPNP > 0
- for (nod = pnp_device_list; nod != NULL; nod = nod->next)
- if (status |= haveseen(dvp, &(nod->dev), checkbits))
- return status;
-#endif
-#ifdef RESOURCE_CHECK
- if (!dvp->id_conflicts)
- status = check_pciconflict(dvp, checkbits);
- else if (bootverbose)
- printf("\tnot checking for resource conflicts ...\n");
-#endif /* RESOURCE_CHECK */
- return(status);
+ if (sensitive)
+ child = device_add_child_after(dev, last_sensitive, name,
+ unit, idev);
+ else
+ child = device_add_child(dev, name, unit, idev);
+ if (child == 0)
+ return;
+ else if (sensitive)
+ last_sensitive = child;
+
+ if (resource_int_value(name, unit, "disabled", &t) == 0 && t != 0)
+ device_disable(child);
}
/*
- * Configure all ISA devices
+ * At 'probe' time, we add all the devices which we know about to the
+ * bus. The generic attach routine will probe and attach them if they
+ * are alive.
*/
-void
-isa_configure()
+static int
+isa_probe(device_t dev)
{
- struct isa_device *dvp;
+ int i;
+ static char buf[] = "isaXXX";
- printf("Probing for devices on the ISA bus:\n");
- /* First probe all the sensitive probes */
- for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &tty_imask);
- for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &bio_imask);
- for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &net_imask);
- for (dvp = isa_devtab_cam; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &cam_imask);
- for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
- if (dvp->id_driver->sensitive_hw)
- config_isadev(dvp, (u_int *)NULL);
-
- /* Then all the bad ones */
- for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &tty_imask);
- for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &bio_imask);
- for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &net_imask);
- for (dvp = isa_devtab_cam; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, &cam_imask);
- for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
- if (!dvp->id_driver->sensitive_hw)
- config_isadev(dvp, (u_int *)NULL);
-
-/*
- * XXX we should really add the tty device to net_imask when the line is
- * switched to SLIPDISC, and then remove it when it is switched away from
- * SLIPDISC. No need to block out ALL ttys during a splimp when only one
- * of them is running slip.
- *
- * XXX actually, blocking all ttys during a splimp doesn't matter so much
- * with sio because the serial interrupt layer doesn't use tty_imask. Only
- * non-serial ttys suffer. It's more stupid that ALL 'net's are blocked
- * during spltty.
- */
-#include "sl.h"
-#if NSL > 0
- net_imask |= tty_imask;
- tty_imask = net_imask;
-#endif
-
- if (bootverbose)
- printf("imasks: bio %x, tty %x, net %x\n",
- bio_imask, tty_imask, net_imask);
+ device_set_desc(dev, "ISA bus");
/*
- * Finish initializing intr_mask[]. Note that the partly
- * constructed masks aren't actually used since we're at splhigh.
- * For fully dynamic initialization, register_intr() and
- * icu_unset() will have to adjust the masks for _all_
- * interrupts and for tty_imask, etc.
+ * Add all devices configured to be attached to isa0.
*/
- for (dvp = isa_devtab_tty; dvp->id_driver; dvp++)
- register_imask(dvp, tty_imask);
- for (dvp = isa_devtab_bio; dvp->id_driver; dvp++)
- register_imask(dvp, bio_imask);
- for (dvp = isa_devtab_net; dvp->id_driver; dvp++)
- register_imask(dvp, net_imask);
- for (dvp = isa_devtab_cam; dvp->id_driver; dvp++)
- register_imask(dvp, cam_imask);
- for (dvp = isa_devtab_null; dvp->id_driver; dvp++)
- register_imask(dvp, SWI_CLOCK_MASK);
-}
-
-/*
- * Configure an ISA device.
- */
-static void
-config_isadev(isdp, mp)
- struct isa_device *isdp;
- u_int *mp;
-{
- config_isadev_c(isdp, mp, 0);
-}
-
-void
-reconfig_isadev(isdp, mp)
- struct isa_device *isdp;
- u_int *mp;
-{
- config_isadev_c(isdp, mp, 1);
-}
-
-static void
-config_isadev_c(isdp, mp, reconfig)
- struct isa_device *isdp;
- u_int *mp;
- int reconfig;
-{
- u_int checkbits;
- int id_alive;
- int last_alive;
- struct isa_driver *dp = isdp->id_driver;
-
- if (!isdp->id_enabled) {
- if (bootverbose)
- printf("%s%d: disabled, not probed.\n", dp->name, isdp->id_unit);
- return;
+ sprintf(buf, "isa%d", device_get_unit(dev));
+ for (i = resource_query_string(-1, "at", buf);
+ i != -1;
+ i = resource_query_string(i, "at", buf)) {
+ isa_add_device(dev, resource_query_name(i),
+ resource_query_unit(i));
}
- checkbits = CC_DRQ | CC_IOADDR | CC_MEMADDR;
- if (!reconfig && haveseen_isadev(isdp, checkbits))
- return;
- if (!reconfig && isdp->id_maddr) {
- isdp->id_maddr -= ISA_HOLE_START;
- isdp->id_maddr += atdevbase;
- }
- if (reconfig) {
- last_alive = isdp->id_alive;
- isdp->id_reconfig = 1;
- }
- else {
- last_alive = 0;
- isdp->id_reconfig = 0;
- }
- id_alive = (*dp->probe)(isdp);
- if (id_alive) {
- /*
- * Only print the I/O address range if id_alive != -1
- * Right now this is a temporary fix just for the new
- * NPX code so that if it finds a 486 that can use trap
- * 16 it will not report I/O addresses.
- * Rod Grimes 04/26/94
- */
- if (!isdp->id_reconfig) {
- printf("%s%d", dp->name, isdp->id_unit);
- if (id_alive != -1) {
- if (isdp->id_iobase == -1)
- printf(" at");
- else {
- printf(" at 0x%x", isdp->id_iobase);
- if (isdp->id_iobase + id_alive - 1 !=
- isdp->id_iobase) {
- printf("-0x%x",
- isdp->id_iobase + id_alive - 1);
- }
- }
- }
- if (isdp->id_irq)
- printf(" irq %d", ffs(isdp->id_irq) - 1);
- if (isdp->id_drq != -1)
- printf(" drq %d", isdp->id_drq);
- if (isdp->id_maddr)
- printf(" maddr 0x%lx", kvtop(isdp->id_maddr));
- if (isdp->id_msize)
- printf(" msize %d", isdp->id_msize);
- if (isdp->id_flags)
- printf(" flags 0x%x", isdp->id_flags);
- if (isdp->id_iobase && !(isdp->id_iobase & 0xf300)) {
- printf(" on motherboard");
- } else if (isdp->id_iobase >= 0x1000 &&
- !(isdp->id_iobase & 0x300)) {
- printf (" on eisa slot %d",
- isdp->id_iobase >> 12);
- } else {
- printf (" on isa");
- }
- printf("\n");
- /*
- * Check for conflicts again. The driver may have
- * changed *dvp. We should weaken the early check
- * since the driver may have been able to change
- * *dvp to avoid conflicts if given a chance. We
- * already skip the early check for IRQs and force
- * a check for IRQs in the next group of checks.
- */
- checkbits |= CC_ATTACH | CC_IRQ;
- if (haveseen_isadev(isdp, checkbits))
- return;
- isdp->id_alive = id_alive;
- }
- (*dp->attach)(isdp);
- if (isdp->id_irq != 0 && isdp->id_intr == NULL)
- printf("%s%d: irq with no handler\n",
- dp->name, isdp->id_unit);
- if (isdp->id_irq != 0 && isdp->id_intr != NULL) {
-#ifdef APIC_IO
- /*
- * Some motherboards use upper IRQs for traditional
- * ISA INTerrupt sources. In particular we have
- * seen the secondary IDE connected to IRQ20.
- * This code detects and fixes this situation.
- */
- u_int apic_mask;
- int rirq;
- apic_mask = isa_apic_mask(isdp->id_irq);
- if (apic_mask != isdp->id_irq) {
- rirq = ffs(isdp->id_irq) - 1;
- isdp->id_irq = apic_mask;
- undirect_isa_irq(rirq); /* free for ISA */
- }
-#endif /* APIC_IO */
- register_intr(ffs(isdp->id_irq) - 1, isdp->id_id,
- isdp->id_ri_flags, isdp->id_intr,
- mp, isdp->id_unit);
- }
- } else {
- if (isdp->id_reconfig) {
- (*dp->attach)(isdp); /* reconfiguration attach */
- }
- if (!last_alive) {
- if (!isdp->id_reconfig) {
- printf("%s%d not found",
- dp->name, isdp->id_unit);
- if (isdp->id_iobase != -1)
- printf(" at 0x%x", isdp->id_iobase);
- printf("\n");
- }
- } else {
-#if 0
- /* This code has not been tested.... */
- if (isdp->id_irq != 0 && isdp->id_intr != NULL) {
- icu_unset(ffs(isdp->id_irq) - 1,
- isdp->id_intr);
- if (mp)
- INTRUNMASK(*mp, isdp->id_irq);
- }
-#else
- printf ("icu_unset() not supported here ...\n");
-#endif
- }
+ /*
+ * and isa?
+ */
+ for (i = resource_query_string(-1, "at", "isa");
+ i != -1;
+ i = resource_query_string(i, "at", "isa")) {
+ isa_add_device(dev, resource_query_name(i),
+ resource_query_unit(i));
}
-}
-static caddr_t dma_bouncebuf[8];
-static u_int dma_bouncebufsize[8];
-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;
+ isa_wrap_old_drivers();
-#define VALID_DMA_MASK (7)
+ return 0;
+}
-/* high byte of address is stored in this port for i-th dma channel */
-static int dmapageport[8] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
+extern device_t isa_bus_device;
-/*
- * Setup a DMA channel's bounce buffer.
- */
-void
-isa_dmainit(chan, bouncebufsize)
- int chan;
- u_int bouncebufsize;
+static int
+isa_attach(device_t dev)
{
- 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;
+ /*
+ * Arrange for bus_generic_attach(dev) to be called later.
+ */
+ isa_bus_device = dev;
+ return 0;
}
-/*
- * Register a DMA channel's usage. Usually called from a device driver
- * in open() or during its initialization.
- */
-int
-isa_dma_acquire(chan)
- int chan;
+static void
+isa_print_child(device_t bus, device_t dev)
{
-#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);
+ struct isa_device *id = DEVTOISA(dev);
+
+ if (id->id_port[0] > 0 || id->id_port[1] > 0
+ || id->id_maddr[0] > 0 || id->id_maddr[1] > 0
+ || id->id_irq[0] >= 0 || id->id_irq[1] >= 0
+ || id->id_drq[0] >= 0 || id->id_drq[1] >= 0)
+ printf(" at");
+ if (id->id_port[0] > 0 && id->id_port[1] > 0) {
+ printf(" ports %#x", (u_int)id->id_port[0]);
+ if (id->id_portsize[0] > 1)
+ printf("-%#x", (u_int)(id->id_port[0]
+ + id->id_portsize[0] - 1));
+ printf(" and %#x", (u_int)id->id_port[1]);
+ if (id->id_portsize[1] > 1)
+ printf("-%#x", (u_int)(id->id_port[1]
+ + id->id_portsize[1] - 1));
+ } else if (id->id_port[0] > 0) {
+ printf(" port %#x", (u_int)id->id_port[0]);
+ if (id->id_portsize[0] > 1)
+ printf("-%#x", (u_int)(id->id_port[0]
+ + id->id_portsize[0] - 1));
+ } else if (id->id_port[1] > 0) {
+ printf(" port %#x", (u_int)id->id_port[1]);
+ if (id->id_portsize[1] > 1)
+ printf("-%#x", (u_int)(id->id_port[1]
+ + id->id_portsize[1] - 1));
+ }
+ if (id->id_maddr[0] && id->id_maddr[1]) {
+ printf(" iomem %#x", (u_int)id->id_maddr[0]);
+ if (id->id_msize[0])
+ printf("-%#x", (u_int)(id->id_maddr[0]
+ + id->id_msize[0] - 1));
+ printf(" and %#x", (u_int)id->id_maddr[1]);
+ if (id->id_msize[1])
+ printf("-%#x", (u_int)(id->id_maddr[1]
+ + id->id_msize[1] - 1));
+ } else if (id->id_maddr[0]) {
+ printf(" iomem %#x", (u_int)id->id_maddr[0]);
+ if (id->id_msize[0])
+ printf("-%#x", (u_int)(id->id_maddr[0]
+ + id->id_msize[0] - 1));
+ } else if (id->id_maddr[1]) {
+ printf(" iomem %#x", (u_int)id->id_maddr[1]);
+ if (id->id_msize[1])
+ printf("-%#x", (u_int)(id->id_maddr[1]
+ + id->id_msize[1] - 1));
+ }
+ if (id->id_irq[0] >= 0 && id->id_irq[1] >= 0)
+ printf(" irqs %d and %d", id->id_irq[0], id->id_irq[1]);
+ else if (id->id_irq[0] >= 0)
+ printf(" irq %d", id->id_irq[0]);
+ else if (id->id_irq[1] >= 0)
+ printf(" irq %d", id->id_irq[1]);
+ if (id->id_drq[0] >= 0 && id->id_drq[1] >= 0)
+ printf(" drqs %d and %d", id->id_drq[0], id->id_drq[1]);
+ else if (id->id_drq[0] >= 0)
+ printf(" drq %d", id->id_drq[0]);
+ else if (id->id_drq[1] >= 0)
+ printf(" drq %d", id->id_drq[1]);
+
+ if (id->id_flags)
+ printf(" flags %#x", id->id_flags);
+
+ printf(" on %s%d",
+ device_get_name(bus), device_get_unit(bus));
}
-/*
- * 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;
+static int
+isa_read_ivar(device_t bus, device_t dev, int index, uintptr_t * result)
{
-#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);
+ struct isa_device* idev = DEVTOISA(dev);
+
+ switch (index) {
+ case ISA_IVAR_PORT_0:
+ *result = idev->id_port[0];
+ break;
+ case ISA_IVAR_PORT_1:
+ *result = idev->id_port[1];
+ break;
+ case ISA_IVAR_PORTSIZE_0:
+ *result = idev->id_portsize[0];
+ break;
+ case ISA_IVAR_PORTSIZE_1:
+ *result = idev->id_portsize[1];
+ break;
+ case ISA_IVAR_MADDR_0:
+ *result = idev->id_maddr[0];
+ break;
+ case ISA_IVAR_MADDR_1:
+ *result = idev->id_maddr[1];
+ break;
+ case ISA_IVAR_MSIZE_0:
+ *result = idev->id_msize[0];
+ break;
+ case ISA_IVAR_MSIZE_1:
+ *result = idev->id_msize[1];
+ break;
+ case ISA_IVAR_IRQ_0:
+ *result = idev->id_irq[0];
+ break;
+ case ISA_IVAR_IRQ_1:
+ *result = idev->id_irq[1];
+ break;
+ case ISA_IVAR_DRQ_0:
+ *result = idev->id_drq[0];
+ break;
+ case ISA_IVAR_DRQ_1:
+ *result = idev->id_drq[1];
+ break;
+ case ISA_IVAR_FLAGS:
+ *result = idev->id_flags;
+ break;
+ }
+ return ENOENT;
}
/*
- * isa_dmacascade(): program 8237 DMA controller channel to accept
- * external dma control by a board.
+ * XXX -- this interface is pretty much irrelevant in the presence of
+ * BUS_ALLOC_RESOURCE / BUS_RELEASE_RESOURCE (at least for the ivars which
+ * are defined at this point).
*/
-void
-isa_dmacascade(chan)
- int chan;
+static int
+isa_write_ivar(device_t bus, device_t dev,
+ int index, uintptr_t value)
{
-#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);
+ struct isa_device* idev = DEVTOISA(dev);
+
+ switch (index) {
+ case ISA_IVAR_PORT_0:
+ idev->id_port[0] = value;
+ break;
+ case ISA_IVAR_PORT_1:
+ idev->id_port[1] = value;
+ break;
+ case ISA_IVAR_PORTSIZE_0:
+ idev->id_portsize[0] = value;
+ break;
+ case ISA_IVAR_PORTSIZE_1:
+ idev->id_portsize[1] = value;
+ break;
+ case ISA_IVAR_MADDR_0:
+ idev->id_maddr[0] = value;
+ break;
+ case ISA_IVAR_MADDR_1:
+ idev->id_maddr[1] = value;
+ break;
+ case ISA_IVAR_MSIZE_0:
+ idev->id_msize[0] = value;
+ break;
+ case ISA_IVAR_MSIZE_1:
+ idev->id_msize[1] = value;
+ break;
+ case ISA_IVAR_IRQ_0:
+ idev->id_irq[0] = value;
+ break;
+ case ISA_IVAR_IRQ_1:
+ idev->id_irq[1] = value;
+ break;
+ case ISA_IVAR_DRQ_0:
+ idev->id_drq[0] = value;
+ break;
+ case ISA_IVAR_DRQ_1:
+ idev->id_drq[1] = value;
+ break;
+ case ISA_IVAR_FLAGS:
+ idev->id_flags = value;
+ break;
+ default:
+ return (ENOENT);
}
+ return (0);
}
/*
- * isa_dmastart(): program 8237 DMA controller channel, avoid page alignment
- * problems by using a bounce buffer.
+ * This implementation simply passes the request up to the parent
+ * bus, which in our case is the special i386 nexus, substituting any
+ * configured values if the caller defaulted. We can get away with
+ * this because there is no special mapping for ISA resources on an Intel
+ * platform. When porting this code to another architecture, it may be
+ * necessary to interpose a mapping layer here.
*/
-void
-isa_dmastart(int flags, caddr_t addr, u_int nbytes, int chan)
+static struct resource *
+isa_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
{
- vm_offset_t phys;
- int waport;
- caddr_t newaddr;
+ int isdefault;
+ struct resource *rv, **rvp = 0;
+ struct isa_device *id = DEVTOISA(child);
-#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);
- }
-
- if ((chan & 4) == 0) {
+ if (child) {
/*
- * Program one of DMA channels 0..3. These are
- * byte mode channels.
+ * If this is our child, then use the isa_device to find
+ * defaults and to record results.
*/
- /* 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);
+ if (device_get_devclass(device_get_parent(child)) == isa_devclass)
+ id = DEVTOISA(child);
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);
- } 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));
+ id = NULL;
+ } else
+ id = NULL;
+ isdefault = (id != NULL && start == 0UL && end == ~0UL && *rid == 0);
+ if (*rid > 1)
+ return 0;
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (isdefault && id->id_irq[0] >= 0) {
+ start = id->id_irq[0];
+ end = id->id_irq[0];
+ count = 1;
}
- 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);
+ if (id)
+ rvp = &id->id_irqres[*rid];
+ break;
+
+ case SYS_RES_DRQ:
+ if (isdefault && id->id_drq[0] >= 0) {
+ start = id->id_drq[0];
+ end = id->id_drq[0];
+ count = 1;
+ }
+ if (id)
+ rvp = &id->id_drqres[*rid];
+ break;
+
+ case SYS_RES_MEMORY:
+ if (isdefault && id->id_maddr[0]) {
+ start = id->id_maddr[0];
+ count = max(count, (u_long)id->id_msize[0]);
+ end = id->id_maddr[0] + count;
+ }
+ if (id)
+ rvp = &id->id_memres[*rid];
+ break;
+
+ case SYS_RES_IOPORT:
+ if (isdefault && id->id_port[0]) {
+ start = id->id_port[0];
+ count = max(count, (u_long)id->id_portsize[0]);
+ end = id->id_port[0] + count;
+ }
+ if (id)
+ rvp = &id->id_portres[*rid];
+ break;
- /* unmask channel */
- outb(DMA2_SMSK, chan & 3);
+ default:
+ return 0;
}
-}
-
-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);
- if ((dma_auto_mode & (1 << chan)) == 0)
- outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
-
- if (dma_bounced & (1 << chan)) {
- /* copy bounce buffer on read */
- if (flags & B_READ)
- bcopy(dma_bouncebuf[chan], addr, nbytes);
+ /*
+ * If the client attempts to reallocate a resource without
+ * releasing what was there previously, die horribly so that
+ * he knows how he !@#$ed up.
+ */
+ if (rvp && *rvp != 0)
+ panic("%s%d: (%d, %d) not free for %s%d\n",
+ device_get_name(bus), device_get_unit(bus),
+ type, *rid,
+ device_get_name(child), device_get_unit(child));
- dma_bounced &= ~(1 << chan);
+ /*
+ * nexus_alloc_resource had better not change *rid...
+ */
+ rv = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, type, rid,
+ start, end, count, flags);
+ if (rvp && (*rvp = rv) != 0) {
+ switch (type) {
+ case SYS_RES_MEMORY:
+ id->id_maddr[*rid] = rv->r_start;
+ id->id_msize[*rid] = count;
+ break;
+ case SYS_RES_IOPORT:
+ id->id_port[*rid] = rv->r_start;
+ id->id_portsize[*rid] = count;
+ break;
+ case SYS_RES_IRQ:
+ id->id_irq[*rid] = rv->r_start;
+ break;
+ case SYS_RES_DRQ:
+ id->id_drq[*rid] = rv->r_start;
+ break;
+ }
}
- dma_busy &= ~(1 << chan);
+ return rv;
}
-/*
- * 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)
+isa_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
{
- 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));
-#define ISARAM_END RAM_END
- 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);
-}
+ int rv;
+ struct isa_device *id = DEVTOISA(child);
-/*
- * 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;
+ if (rid > 1)
+ return EINVAL;
- /* channel active? */
- if ((dma_inuse & (1 << chan)) == 0) {
- printf("isa_dmastatus: channel %d not active\n", chan);
- return(-1);
+ switch (type) {
+ case SYS_RES_IRQ:
+ case SYS_RES_DRQ:
+ case SYS_RES_IOPORT:
+ case SYS_RES_MEMORY:
+ break;
+ default:
+ return (ENOENT);
}
- /* channel busy? */
- if (((dma_busy & (1 << chan)) == 0) &&
- (dma_auto_mode & (1 << chan)) == 0 ) {
- printf("chan %d not busy\n", chan);
- return -2 ;
- }
- 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;
- }
+ rv = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, type, rid, r);
- 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 */
+#if 0
+ if (rv) {
+ /* Kludge, isa as a child of pci doesn't have mapping regs */
+ printf("WARNING: isa_release_resource: BUS_RELEASE_RESOURCE() failed: %d\n", rv);
+ rv = 0;
+ }
+#endif
- /*
- * 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 (rv == 0) {
+ switch (type) {
+ case SYS_RES_IRQ:
+ id->id_irqres[rid] = 0;
+ id->id_irq[rid] = -1;
+ break;
+
+ case SYS_RES_DRQ:
+ id->id_drqres[rid] = 0;
+ id->id_drq[rid] = -1;
+ break;
+
+ case SYS_RES_MEMORY:
+ id->id_memres[rid] = 0;
+ id->id_maddr[rid] = 0;
+ id->id_msize[rid] = 0;
+ break;
+
+ case SYS_RES_IOPORT:
+ id->id_portres[rid] = 0;
+ id->id_port[rid] = 0;
+ id->id_portsize[rid] = 0;
+ break;
+
+ default:
+ return ENOENT;
+ }
}
- if (chan >= 4) /* high channels move words */
- cnt *= 2;
- return(cnt);
+ return rv;
}
/*
- * Stop a DMA transfer currently in progress.
+ * We can't use the bus_generic_* versions of these methods because those
+ * methods always pass the bus param as the requesting device, and we need
+ * to pass the child (the i386 nexus knows about this and is prepared to
+ * deal).
*/
-int
-isa_dmastop(int chan)
+static int
+isa_setup_intr(device_t bus, device_t child, struct resource *r,
+ void (*ihand)(void *), void *arg, void **cookiep)
{
- 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 {
- outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
- }
- return(isa_dmastatus(chan));
+ return (BUS_SETUP_INTR(device_get_parent(bus), child, r, ihand, arg,
+ cookiep));
}
-/*
- * Find the highest priority enabled display device. Since we can't
- * distinguish display devices from ttys, depend on display devices
- * being sensitive and before sensitive non-display devices (if any)
- * in isa_devtab_tty.
- *
- * XXX we should add capability flags IAMDISPLAY and ISUPPORTCONSOLES.
- */
-struct isa_device *
-find_display()
+static int
+isa_teardown_intr(device_t bus, device_t child, struct resource *r,
+ void *cookie)
{
- struct isa_device *dvp;
-
- for (dvp = isa_devtab_tty; dvp->id_driver != NULL; dvp++)
- if (dvp->id_driver->sensitive_hw && dvp->id_enabled)
- return (dvp);
- return (NULL);
+ return (BUS_TEARDOWN_INTR(device_get_parent(bus), child, r, cookie));
}
+static device_method_t isa_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, isa_probe),
+ DEVMETHOD(device_attach, isa_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),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, isa_print_child),
+ DEVMETHOD(bus_read_ivar, isa_read_ivar),
+ DEVMETHOD(bus_write_ivar, isa_write_ivar),
+ DEVMETHOD(bus_alloc_resource, isa_alloc_resource),
+ DEVMETHOD(bus_release_resource, isa_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, isa_setup_intr),
+ DEVMETHOD(bus_teardown_intr, isa_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t isa_driver = {
+ "isa",
+ isa_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+
/*
- * find an ISA device in a given isa_devtab_* table, given
- * the table to search, the expected id_driver entry, and the unit number.
- *
- * this function is defined in isa_device.h, and this location is debatable;
- * i put it there because it's useless w/o, and directly operates on
- * the other stuff in that file.
- *
+ * ISA can be attached to a PCI-ISA bridge or directly to the nexus.
*/
-
-struct isa_device *
-find_isadev(table, driverp, unit)
- struct isa_device *table;
- struct isa_driver *driverp;
- int unit;
-{
- if (driverp == NULL) /* sanity check */
- return (NULL);
-
- while ((table->id_driver != driverp) || (table->id_unit != unit)) {
- if (table->id_driver == 0)
- return NULL;
-
- table++;
- }
-
- return (table);
-}
+DRIVER_MODULE(isa, isab, isa_driver, isa_devclass, 0, 0);
+DRIVER_MODULE(isa, nexus, isa_driver, isa_devclass, 0, 0);
diff --git a/sys/i386/isa/isa_compat.c b/sys/i386/isa/isa_compat.c
new file mode 100644
index 0000000..82e6185
--- /dev/null
+++ b/sys/i386/isa/isa_compat.c
@@ -0,0 +1,255 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/resource.h>
+#include <isa/isavar.h>
+#include <i386/isa/isa_compat.h>
+#include <i386/isa/isa_device.h>
+
+struct isa_compat_resources {
+ struct resource *ports;
+ struct resource *memory;
+ struct resource *drq;
+ struct resource *irq;
+};
+
+int
+isa_compat_nextid(void)
+{
+ static int id = 2; /* id_id of -1, 0 and 1 are "used" */
+
+ return id++;
+}
+
+static void
+isa_compat_alloc_resources(device_t dev, struct isa_compat_resources *res)
+{
+ int rid;
+
+ if (isa_get_port(dev) != -1) {
+ rid = 0;
+ res->ports = bus_alloc_resource(dev, SYS_RES_IOPORT,
+ &rid, 0ul, ~0ul, 1,
+ RF_ACTIVE);
+ if (res->ports == NULL)
+ printf("isa_compat: didn't get ports for %s\n",
+ device_get_name(dev));
+ } else
+ res->ports = 0;
+
+ if (isa_get_maddr(dev) != 0) {
+ rid = 0;
+ res->memory = bus_alloc_resource(dev, SYS_RES_MEMORY,
+ &rid, 0ul, ~0ul, 1,
+ RF_ACTIVE);
+ if (res->memory == NULL)
+ printf("isa_compat: didn't get memory for %s\n",
+ device_get_name(dev));
+ } else
+ res->memory = 0;
+
+ if (isa_get_drq(dev) != -1) {
+ rid = 0;
+ res->drq = bus_alloc_resource(dev, SYS_RES_DRQ,
+ &rid, 0ul, ~0ul, 1,
+ RF_ACTIVE);
+ if (res->drq == NULL)
+ printf("isa_compat: didn't get drq for %s\n",
+ device_get_name(dev));
+ } else
+ res->drq = 0;
+
+ if (isa_get_irq(dev) != -1) {
+ rid = 0;
+ res->irq = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &rid, 0ul, ~0ul, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (res->irq == NULL)
+ printf("isa_compat: didn't get irq for %s\n",
+ device_get_name(dev));
+ } else
+ res->irq = 0;
+}
+
+static void
+isa_compat_release_resources(device_t dev, struct isa_compat_resources *res)
+{
+ if (res->ports) {
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, res->ports);
+ res->ports = 0;
+ }
+ if (res->memory) {
+ bus_release_resource(dev, SYS_RES_MEMORY, 0, res->memory);
+ res->memory = 0;
+ }
+ if (res->drq) {
+ bus_release_resource(dev, SYS_RES_DRQ, 0, res->drq);
+ res->drq = 0;
+ }
+ if (res->irq) {
+ bus_release_resource(dev, SYS_RES_IRQ, 0, res->irq);
+ res->irq = 0;
+ }
+}
+
+static int
+isa_compat_probe(device_t dev)
+{
+ struct isa_device *dvp = device_get_softc(dev);
+ struct isa_compat_resources res;
+
+ bzero(&res, sizeof(res));
+ /*
+ * Fill in the isa_device fields.
+ */
+ dvp->id_id = isa_compat_nextid();
+ dvp->id_driver = device_get_driver(dev)->priv;
+ dvp->id_iobase = isa_get_port(dev);
+ dvp->id_irq = (1 << isa_get_irq(dev));
+ dvp->id_drq = isa_get_drq(dev);
+ dvp->id_maddr = (void *)isa_get_maddr(dev);
+ dvp->id_msize = isa_get_msize(dev);
+ dvp->id_unit = device_get_unit(dev);
+ dvp->id_flags = isa_get_flags(dev);
+ dvp->id_enabled = device_is_enabled(dev);
+
+ /*
+ * Do the wrapped probe.
+ */
+ if (dvp->id_driver->probe) {
+ int portsize;
+ isa_compat_alloc_resources(dev, &res);
+ if (res.memory)
+ dvp->id_maddr = rman_get_virtual(res.memory);
+ else
+ dvp->id_maddr = 0;
+ portsize = dvp->id_driver->probe(dvp);
+ isa_compat_release_resources(dev, &res);
+ if (portsize != 0) {
+ if (portsize > 0)
+ isa_set_portsize(dev, portsize);
+ if (dvp->id_iobase != isa_get_port(dev))
+ isa_set_port(dev, dvp->id_iobase);
+ if (dvp->id_irq != (1 << isa_get_irq(dev)))
+ isa_set_irq(dev, ffs(dvp->id_irq) - 1);
+ if (dvp->id_drq != isa_get_drq(dev))
+ isa_set_drq(dev, dvp->id_drq);
+ if (dvp->id_maddr != (void *) isa_get_maddr(dev))
+ isa_set_maddr(dev, (int) dvp->id_maddr);
+ if (dvp->id_msize != isa_get_msize(dev))
+ isa_set_msize(dev, dvp->id_msize);
+ return 0;
+ }
+ }
+ return ENXIO;
+}
+
+static int
+isa_compat_attach(device_t dev)
+{
+ struct isa_device *dvp = device_get_softc(dev);
+ struct isa_compat_resources res;
+ int error;
+
+ bzero(&res, sizeof(res));
+ isa_compat_alloc_resources(dev, &res);
+ if (dvp->id_driver->attach)
+ dvp->id_driver->attach(dvp);
+ if (res.irq && dvp->id_irq && dvp->id_intr) {
+ void *ih;
+
+ error = BUS_SETUP_INTR(device_get_parent(dev), dev,
+ res.irq,
+ dvp->id_intr,
+ (void *)(uintptr_t)dvp->id_unit,
+ &ih);
+ if (error)
+ printf("isa_compat_attach: failed to setup intr: %d\n",
+ error);
+ }
+ return 0;
+}
+
+static device_method_t isa_compat_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, isa_compat_probe),
+ DEVMETHOD(device_attach, isa_compat_attach),
+
+ { 0, 0 }
+};
+
+/*
+ * Create a new style driver around each old isa driver.
+ */
+void
+isa_wrap_old_drivers(void)
+{
+ int i;
+ struct old_isa_driver *op;
+ devclass_t isa_devclass = devclass_find("isa");
+
+ for (i = 0, op = &old_drivers[0]; i < old_drivers_count; i++, op++) {
+ driver_t *driver;
+ driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT);
+ if (!driver)
+ continue;
+ bzero(driver, sizeof(driver_t));
+ driver->name = op->driver->name;
+ driver->methods = isa_compat_methods;
+ driver->type = op->type;
+ driver->softc = sizeof(struct isa_device *);
+ driver->priv = op->driver;
+ devclass_add_driver(isa_devclass, driver);
+ }
+}
+
+int
+haveseen_isadev(dvp, checkbits)
+ struct isa_device *dvp;
+ u_int checkbits;
+{
+ printf("haveseen_isadev() called - FIXME!\n");
+ return 0;
+}
+
+void
+reconfig_isadev(isdp, mp)
+ struct isa_device *isdp;
+ u_int *mp;
+{
+ printf("reconfig_isadev() called - FIXME!\n");
+}
diff --git a/sys/i386/isa/isa_compat.h b/sys/i386/isa/isa_compat.h
new file mode 100644
index 0000000..5e48b89
--- /dev/null
+++ b/sys/i386/isa/isa_compat.h
@@ -0,0 +1,378 @@
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include "vt.h"
+#include "bt.h"
+#include "adv.h"
+#include "aha.h"
+#include "wdc.h"
+#include "mse.h"
+#include "ar.h"
+#include "cs.h"
+#include "cx.h"
+#include "ed.h"
+#include "el.h"
+#include "ep.h"
+#include "ex.h"
+#include "fe.h"
+#include "ie.h"
+#include "le.h"
+#include "lnc.h"
+#include "rdp.h"
+#include "sr.h"
+#include "wl.h"
+#include "ze.h"
+#include "zp.h"
+#include "oltr.h"
+#include "pas.h"
+#include "sb.h"
+#include "sbxvi.h"
+#include "sbmidi.h"
+#include "awe.h"
+#include "gus.h"
+#include "mss.h"
+#include "css.h"
+#include "sscape.h"
+#include "trix.h"
+#include "opl.h"
+#include "mpu.h"
+#include "uart.h"
+#include "pca.h"
+#include "mcd.h"
+#include "scd.h"
+#include "matcd.h"
+#include "wt.h"
+#include "ctx.h"
+#include "spigot.h"
+#include "gp.h"
+#include "gsc.h"
+#include "joy.h"
+#include "cy.h"
+#include "dgb.h"
+#include "dgm.h"
+#include "labpc.h"
+#include "rc.h"
+#include "rp.h"
+#include "tw.h"
+#include "si.h"
+#include "asc.h"
+#include "stl.h"
+#include "stli.h"
+#include "loran.h"
+#include "pcf.h"
+#include "isic.h"
+#include "tina.h"
+#include "ppc.h"
+
+struct old_isa_driver {
+ int type;
+ struct isa_driver *driver;
+};
+
+extern struct isa_driver vtdriver;
+extern struct isa_driver btdriver;
+extern struct isa_driver advdriver;
+extern struct isa_driver ahadriver;
+extern struct isa_driver wdcdriver;
+extern struct isa_driver msedriver;
+extern struct isa_driver ardriver;
+extern struct isa_driver csdriver;
+extern struct isa_driver cxdriver;
+extern struct isa_driver eddriver;
+extern struct isa_driver eldriver;
+extern struct isa_driver epdriver;
+extern struct isa_driver exdriver;
+extern struct isa_driver fedriver;
+extern struct isa_driver iedriver;
+extern struct isa_driver ledriver;
+extern struct isa_driver lncdriver;
+extern struct isa_driver rdpdriver;
+extern struct isa_driver srdriver;
+extern struct isa_driver wldriver;
+extern struct isa_driver zedriver;
+extern struct isa_driver zpdriver;
+extern struct isa_driver oltrdriver;
+extern struct isa_driver pasdriver;
+extern struct isa_driver sbdriver;
+extern struct isa_driver sbxvidriver;
+extern struct isa_driver sbmididriver;
+extern struct isa_driver awedriver;
+extern struct isa_driver gusdriver;
+extern struct isa_driver mssdriver;
+extern struct isa_driver cssdriver;
+extern struct isa_driver sscapedriver;
+extern struct isa_driver trixdriver;
+extern struct isa_driver sscape_mssdriver;
+extern struct isa_driver opldriver;
+extern struct isa_driver mpudriver;
+extern struct isa_driver uartdriver;
+extern struct isa_driver pcadriver;
+extern struct isa_driver mcddriver;
+extern struct isa_driver scddriver;
+extern struct isa_driver matcddriver;
+extern struct isa_driver wtdriver;
+extern struct isa_driver ctxdriver;
+extern struct isa_driver spigotdriver;
+extern struct isa_driver gpdriver;
+extern struct isa_driver gscdriver;
+extern struct isa_driver joydriver;
+extern struct isa_driver cydriver;
+extern struct isa_driver dgbdriver;
+extern struct isa_driver dgmdriver;
+extern struct isa_driver labpcdriver;
+extern struct isa_driver rcdriver;
+extern struct isa_driver rpdriver;
+extern struct isa_driver twdriver;
+extern struct isa_driver sidriver;
+extern struct isa_driver ascdriver;
+extern struct isa_driver stldriver;
+extern struct isa_driver stlidriver;
+extern struct isa_driver lorandriver;
+extern struct isa_driver pcfdriver;
+extern struct isa_driver isicdriver;
+extern struct isa_driver tinadriver;
+extern struct isa_driver ppcdriver;
+
+
+static struct old_isa_driver old_drivers[] = {
+
+/* Sensitive TTY */
+
+/* Sensitive BIO */
+
+/* Sensitive NET */
+#if NED > 0
+ { DRIVER_TYPE_NET, &eddriver },
+#endif
+#if NFE > 0
+ { DRIVER_TYPE_NET, &fedriver },
+#endif
+#if NRDP > 0
+ { DRIVER_TYPE_NET, &rdpdriver },
+#endif
+
+/* Sensitive CAM */
+
+/* TTY */
+
+#if NVT > 0
+ { DRIVER_TYPE_TTY, &vtdriver },
+#endif
+#if NMSE > 0
+ { DRIVER_TYPE_TTY, &msedriver },
+#endif
+#if NPCA > 0
+ { DRIVER_TYPE_TTY, &pcadriver },
+#endif
+#if NGP > 0
+ { DRIVER_TYPE_TTY, &gpdriver },
+#endif
+#if NGSC > 0
+ { DRIVER_TYPE_TTY, &gscdriver },
+#endif
+#if NCY > 0
+ { DRIVER_TYPE_TTY, &cydriver },
+#endif
+#if NDGB > 0
+ { DRIVER_TYPE_TTY, &dgbdriver },
+#endif
+#if NDGM > 0
+ { DRIVER_TYPE_TTY, &dgmdriver },
+#endif
+#if NLABPC > 0
+ { DRIVER_TYPE_TTY, &labpcdriver },
+#endif
+#if NRCD > 0
+ { DRIVER_TYPE_TTY, &rcdriver },
+#endif
+#if NRP > 0
+ { DRIVER_TYPE_TTY, &rpdriver },
+#endif
+#if NTW > 0
+ { DRIVER_TYPE_TTY, &twdriver },
+#endif
+#if NSI > 0
+ { DRIVER_TYPE_TTY, &sidriver },
+#endif
+#if NASC > 0
+ { DRIVER_TYPE_TTY, &ascdriver },
+#endif
+#if NSTL > 0
+ { DRIVER_TYPE_TTY, &stldriver },
+#endif
+#if NSTLI > 0
+ { DRIVER_TYPE_TTY, &stlidriver },
+#endif
+#if NLORAN > 0
+ { DRIVER_TYPE_TTY, &lorandriver },
+#endif
+#if NPPC > 0
+ { DRIVER_TYPE_TTY, &ppcdriver },
+#endif
+
+/* BIO */
+
+#if NWDC > 0
+ { DRIVER_TYPE_BIO, &wdcdriver },
+#endif
+#if NMCD > 0
+ { DRIVER_TYPE_BIO, &mcddriver },
+#endif
+#if NSCD > 0
+ { DRIVER_TYPE_BIO, &scddriver },
+#endif
+#if NMATCD > 0
+ { DRIVER_TYPE_BIO, &matcddriver },
+#endif
+#if NWT > 0
+ { DRIVER_TYPE_BIO, &wtdriver },
+#endif
+
+/* NET */
+
+#if NIE > 0
+ { DRIVER_TYPE_NET, &iedriver },
+#endif
+#if NEP > 0
+ { DRIVER_TYPE_NET, &epdriver },
+#endif
+#if NEX > 0
+ { DRIVER_TYPE_NET, &exdriver },
+#endif
+#if NLE > 0
+ { DRIVER_TYPE_NET, &ledriver },
+#endif
+#if NLNC > 0
+ { DRIVER_TYPE_NET, &lncdriver },
+#endif
+#if NZE > 0
+ { DRIVER_TYPE_NET, &zedriver },
+#endif
+#if NZP > 0
+ { DRIVER_TYPE_NET, &zpdriver },
+#endif
+#if NCS > 0
+ { DRIVER_TYPE_NET, &csdriver },
+#endif
+#if NAR > 0
+ { DRIVER_TYPE_NET, &ardriver },
+#endif
+#if NCX > 0
+ { DRIVER_TYPE_NET, &cxdriver },
+#endif
+#if NEL > 0
+ { DRIVER_TYPE_NET, &eldriver },
+#endif
+#if NSR > 0
+ { DRIVER_TYPE_NET, &srdriver },
+#endif
+#if NWL > 0
+ { DRIVER_TYPE_NET, &wldriver },
+#endif
+#if NPCF > 0
+ { DRIVER_TYPE_NET, &pcfdriver },
+#endif
+#if NISIC > 0
+ { DRIVER_TYPE_NET, &isicdriver },
+#endif
+#if NTINA > 0
+ { DRIVER_TYPE_NET, &tinadriver },
+#endif
+
+/* CAM */
+
+#if NBT > 0
+ { DRIVER_TYPE_CAM, &btdriver },
+#endif
+#if NADV > 0
+ { DRIVER_TYPE_CAM, &advdriver },
+#endif
+#if NAHA > 0
+ { DRIVER_TYPE_CAM, &ahadriver },
+#endif
+
+/* MISC */
+
+#if NOLTR > 0
+ { DRIVER_TYPE_MISC, &oltrdriver },
+#endif
+#if NPAS > 0
+ { DRIVER_TYPE_MISC, &pasdriver },
+#endif
+#if NSB > 0
+ { DRIVER_TYPE_MISC, &sbdriver },
+#endif
+#if NSBVXI > 0
+ { DRIVER_TYPE_MISC, &sbxvidriver },
+#endif
+#if NSBMIDI > 0
+ { DRIVER_TYPE_MISC, &sbmididriver },
+#endif
+#if NAWE > 0
+ { DRIVER_TYPE_MISC, &awedriver },
+#endif
+#if NGUS > 0
+ { DRIVER_TYPE_MISC, &gusdriver },
+#endif
+#if NMSS > 0
+ { DRIVER_TYPE_MISC, &mssdriver },
+#endif
+#if NCSS > 0
+ { DRIVER_TYPE_MISC, &cssdriver },
+#endif
+#if NSSCAPE > 0
+ { DRIVER_TYPE_MISC, &sscapedriver },
+#endif
+#if NTRIX > 0
+ { DRIVER_TYPE_MISC, &trixdriver },
+#endif
+#if NSSCAPE > 0
+ { DRIVER_TYPE_MISC, &sscape_mssdriver },
+#endif
+#if NOPL > 0
+ { DRIVER_TYPE_MISC, &opldriver },
+#endif
+#if NMPU > 0
+ { DRIVER_TYPE_MISC, &mpudriver },
+#endif
+#if NUART > 0
+ { DRIVER_TYPE_MISC, &uartdriver },
+#endif
+#if NCTX > 0
+ { DRIVER_TYPE_MISC, &ctxdriver },
+#endif
+#if NSPIGOT > 0
+ { DRIVER_TYPE_MISC, &spigotdriver },
+#endif
+#if NJOY > 0
+ { DRIVER_TYPE_MISC, &joydriver },
+#endif
+
+};
+
+#define old_drivers_count (sizeof(old_drivers) / sizeof(old_drivers[0]))
diff --git a/sys/i386/isa/isa_device.h b/sys/i386/isa/isa_device.h
index d23f701..a7c1022 100644
--- a/sys/i386/isa/isa_device.h
+++ b/sys/i386/isa/isa_device.h
@@ -31,12 +31,16 @@
* SUCH DAMAGE.
*
* from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91
- * $Id: isa_device.h,v 1.56 1998/10/22 05:58:39 bde Exp $
+ * $Id: isa_device.h,v 1.57 1999/01/17 06:33:43 bde Exp $
*/
#ifndef _I386_ISA_ISA_DEVICE_H_
#define _I386_ISA_ISA_DEVICE_H_
+#ifdef KERNEL
+#include <i386/isa/isa_dma.h>
+#endif
+
/*
* ISA Bus Autoconfiguration
*/
@@ -105,30 +109,9 @@ struct isa_driver {
#ifdef KERNEL
-extern struct isa_device isa_biotab_fdc[];
-extern struct isa_device isa_biotab_wdc[];
-extern struct isa_device isa_devtab_bio[];
-extern struct isa_device isa_devtab_net[];
-extern struct isa_device isa_devtab_cam[];
-extern struct isa_device isa_devtab_null[];
-extern struct isa_device isa_devtab_tty[];
-
-struct isa_device *
- find_display __P((void));
-struct isa_device *
- find_isadev __P((struct isa_device *table, struct isa_driver *driverp,
- int unit));
int haveseen_isadev __P((struct isa_device *dvp, u_int checkbits));
-void isa_configure __P((void));
-void isa_dmacascade __P((int chan));
-void isa_dmadone __P((int flags, caddr_t addr, int nbytes, int chan));
-void isa_dmainit __P((int chan, u_int bouncebufsize));
-void isa_dmastart __P((int flags, caddr_t addr, u_int nbytes, int chan));
-int isa_dma_acquire __P((int chan));
-void isa_dma_release __P((int chan));
-int isa_dmastatus __P((int chan));
-int isa_dmastop __P((int chan));
void reconfig_isadev __P((struct isa_device *isdp, u_int *mp));
+int isa_compat_nextid __P((void));
#endif /* KERNEL */
diff --git a/sys/i386/isa/isa_dma.c b/sys/i386/isa/isa_dma.c
new file mode 100644
index 0000000..abea7f8
--- /dev/null
+++ b/sys/i386/isa/isa_dma.c
@@ -0,0 +1,510 @@
+/*-
+ * 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.c,v 1.117 1998/11/29 15:42:40 phk 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()
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/malloc.h>
+#include <machine/ipl.h>
+#include <machine/md_var.h>
+#ifdef APIC_IO
+#include <machine/smp.h>
+#endif /* APIC_IO */
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/pmap.h>
+#include <i386/isa/isa_device.h>
+#include <i386/isa/intr_machdep.h>
+#include <i386/isa/isa.h>
+#include <i386/isa/ic/i8237.h>
+
+#include <sys/interrupt.h>
+
+#include "pnp.h"
+#if NPNP > 0
+#include <i386/isa/pnp.h>
+#endif
+
+/*
+** Register definitions for DMA controller 1 (channels 0..3):
+*/
+#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 */
+
+/*
+** 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));
+
+static caddr_t dma_bouncebuf[8];
+static u_int dma_bouncebufsize[8];
+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;
+
+#define VALID_DMA_MASK (7)
+
+/* high byte of address is stored in this port for i-th dma channel */
+static int dmapageport[8] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a };
+
+/*
+ * 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);
+}
+
+/*
+ * 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);
+ }
+}
+
+/*
+ * 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);
+ }
+
+ if ((chan & 4) == 0) {
+ /*
+ * Program one of DMA channels 0..3. These are
+ * byte 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(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);
+ } 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);
+ }
+}
+
+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);
+
+ if ((dma_auto_mode & (1 << chan)) == 0)
+ outb(chan & 4 ? DMA2_SMSK : DMA1_SMSK, (chan & 3) | 4);
+
+ 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));
+#define ISARAM_END RAM_END
+ 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 ;
+ }
+ 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;
+ }
+
+ 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 {
+ outb(DMA2_SMSK, (chan & 3) | 4 /* disable mask */);
+ }
+ return(isa_dmastatus(chan));
+}
diff --git a/sys/i386/isa/isa_dma.h b/sys/i386/isa/isa_dma.h
new file mode 100644
index 0000000..3fe234c
--- /dev/null
+++ b/sys/i386/isa/isa_dma.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * from: @(#)isa_device.h 7.1 (Berkeley) 5/9/91
+ * $Id: isa_device.h,v 1.57 1999/01/17 06:33:43 bde Exp $
+ */
+
+#ifndef _I386_ISA_ISA_DMA_H_
+#define _I386_ISA_ISA_DMA_H_
+
+#ifdef KERNEL
+void isa_dmacascade __P((int chan));
+void isa_dmadone __P((int flags, caddr_t addr, int nbytes, int chan));
+void isa_dmainit __P((int chan, u_int bouncebufsize));
+void isa_dmastart __P((int flags, caddr_t addr, u_int nbytes, int chan));
+int isa_dma_acquire __P((int chan));
+void isa_dma_release __P((int chan));
+int isa_dmastatus __P((int chan));
+int isa_dmastop __P((int chan));
+#endif /* KERNEL */
+
+#endif /* !_I386_ISA_ISA_DMA_H_ */
diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c
index 944eb4e..4f7c1e9 100644
--- a/sys/i386/isa/nmi.c
+++ b/sys/i386/isa/nmi.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)isa.c 7.2 (Berkeley) 5/13/91
- * $Id: intr_machdep.c,v 1.16 1999/01/08 19:17:48 bde Exp $
+ * $Id: intr_machdep.c,v 1.17 1999/04/14 14:26:36 bde Exp $
*/
#include "opt_auto_eoi.h"
@@ -328,6 +328,7 @@ isa_get_nameunit(int id)
return ("clk0"); /* XXX may also be sloppy driver */
if (id == 1)
return ("rtc0");
+#if 0
for (dp = isa_devtab_bio; dp->id_driver != NULL; dp++)
if (dp->id_id == id)
goto found_device;
@@ -343,6 +344,7 @@ isa_get_nameunit(int id)
for (dp = isa_devtab_tty; dp->id_driver != NULL; dp++)
if (dp->id_id == id)
goto found_device;
+#endif
return "???";
found_device:
diff --git a/sys/i386/isa/npx.c b/sys/i386/isa/npx.c
index 2371e7b..dc2eb73 100644
--- a/sys/i386/isa/npx.c
+++ b/sys/i386/isa/npx.c
@@ -32,7 +32,7 @@
* SUCH DAMAGE.
*
* from: @(#)npx.c 7.2 (Berkeley) 5/12/91
- * $Id: npx.c,v 1.65 1999/01/08 16:29:59 bde Exp $
+ * $Id: npx.c,v 1.66 1999/03/28 23:28:18 dt Exp $
*/
#include "npx.h"
@@ -43,10 +43,14 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/sysctl.h>
#include <sys/proc.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
#ifdef NPX_DEBUG
#include <sys/syslog.h>
#endif
@@ -64,6 +68,7 @@
#ifndef SMP
#include <machine/clock.h>
#endif
+#include <machine/resource.h>
#include <machine/specialreg.h>
#include <machine/segments.h>
@@ -72,7 +77,6 @@
#include <i386/isa/intr_machdep.h>
#include <i386/isa/isa.h>
#endif
-#include <i386/isa/isa_device.h>
/*
* 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
@@ -83,9 +87,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)))
@@ -119,18 +120,15 @@ 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));
+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,
@@ -191,12 +189,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 */
@@ -213,20 +212,20 @@ 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;
+ npx_intrno = NRSVIDT + 13;
save_eflags = read_eflags();
disable_intr();
save_icu1_mask = inb(IO_ICU1 + 1);
save_icu2_mask = inb(IO_ICU2 + 1);
save_idt_npxintr = idt[npx_intrno];
save_idt_npxtrap = idt[16];
- 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)));
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();
outb(IO_ICU1 + 1, save_icu1_mask);
outb(IO_ICU2 + 1, save_icu2_mask);
@@ -239,8 +238,8 @@ npxprobe(dvp)
}
static int
-npxprobe1(dvp)
- struct isa_device *dvp;
+npx_probe1(dev)
+ device_t dev;
{
#ifndef SMP
u_short control;
@@ -280,21 +279,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.
@@ -335,14 +331,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.
*/
@@ -350,8 +344,30 @@ npxprobe1(dvp)
/*
* npxattach would be too late to set npx0_imask.
*/
- npx0_imask |= dvp->id_irq;
- return (IO_NPXSIZE);
+ npx0_imask |= (1 << 13);
+
+ /*
+ * 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;
+ r = bus_alloc_resource(dev, SYS_RES_IRQ,
+ &rid, 13, 13,
+ 1, RF_ACTIVE);
+ 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.
@@ -363,13 +379,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 */
}
@@ -377,14 +387,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)
@@ -401,23 +412,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 */
}
/*
@@ -494,8 +508,8 @@ npxexit(p)
* solution for signals other than SIGFPE.
*/
void
-npxintr(unit)
- int unit;
+npx_intr(dummy)
+ void *dummy;
{
int code;
struct intrframe *frame;
@@ -518,7 +532,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
@@ -686,4 +700,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/i386/isa/rp.c b/sys/i386/isa/rp.c
index 3ac4ee9..e9357fa 100644
--- a/sys/i386/isa/rp.c
+++ b/sys/i386/isa/rp.c
@@ -1180,7 +1180,6 @@ int
rpattach(dev)
struct isa_device *dev;
{
- struct isa_device *idev;
dev_t rp_dev;
int iobase, unit, /*rpmajor,*/ oldspl;
int num_ports, num_chan, num_aiops;
@@ -1280,13 +1279,6 @@ struct isa_device *dev;
}
}
- idev = find_isadev(isa_devtab_tty, &rpdriver,
- RP_MPMASTER(dev) + rp_pcicount);
- if(idev == NULL) {
- printf("rp%d: master device %d not configured\n",
- dev->id_unit, RP_MPMASTER(dev));
- }
-/* printf("COOL!! Device is found!!\n");
for(rpmajor=0;rpmajor<nchrdev;rpmajor++)
if(cdevsw[rpmajor].d_open == rpopen)
printf("From %d entries: Found entry at major = %d\n",nchrdev,rpmajor);
diff --git a/sys/i386/isa/snd/sound.c b/sys/i386/isa/snd/sound.c
index 6a5a92d..267901e 100644
--- a/sys/i386/isa/snd/sound.c
+++ b/sys/i386/isa/snd/sound.c
@@ -236,7 +236,6 @@ int
pcmattach(struct isa_device * dev)
{
snddev_info *d = NULL ;
- struct isa_device *dvp;
int stat = 0;
dev->id_ointr = pcmintr;
@@ -292,9 +291,7 @@ pcmattach(struct isa_device * dev)
*/
if (dev->id_driver == NULL) {
dev->id_driver = &pcmdriver ;
- dvp=find_isadev(isa_devtab_tty, &pcmdriver, 0);
- if (dvp)
- dev->id_id = dvp->id_id;
+ dev->id_id = isa_compat_nextid();
}
/*
diff --git a/sys/i386/isa/sound/ad1848.c b/sys/i386/isa/sound/ad1848.c
index 243ed78..18751d4 100644
--- a/sys/i386/isa/sound/ad1848.c
+++ b/sys/i386/isa/sound/ad1848.c
@@ -165,6 +165,10 @@ short ipri_to_irq(u_short ipri);
void
adintr(unit)
{
+#if 1
+ /* this isn't ideal but should work */
+ ad1848_interrupt(-1);
+#else
static short unit_to_irq[4] = {9, -1, -1, -1};
struct isa_device *dev;
@@ -183,6 +187,7 @@ adintr(unit)
ad1848_interrupt(unit_to_irq[unit]);
}
}
+#endif
}
static int
diff --git a/sys/i386/isa/wd.c b/sys/i386/isa/wd.c
index fdf1fa6..9db2fee 100644
--- a/sys/i386/isa/wd.c
+++ b/sys/i386/isa/wd.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
- * $Id: wd.c,v 1.192 1999/04/13 19:38:11 peter Exp $
+ * $Id: wd.c,v 1.193 1999/04/13 20:22:30 peter Exp $
*/
/* TODO:
@@ -73,6 +73,7 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/conf.h>
+#include <sys/bus.h>
#include <sys/disklabel.h>
#include <sys/diskslice.h>
#include <sys/buf.h>
@@ -400,10 +401,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;
@@ -418,14 +419,22 @@ wdattach(struct isa_device *dvp)
} else
bufq_init(&wdtab[dvp->id_unit].controller_queue);
- for (wdup = isa_biotab_wdc; wdup->id_driver != 0; wdup++) {
- if (wdup->id_iobase != dvp->id_iobase)
+ 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;
- lunit = wdup->id_unit;
+
+ lunit = resource_query_unit(i);
if (lunit >= NWD)
continue;
- unit = wdup->id_physid;
+ 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)
@@ -450,7 +459,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) {
diff --git a/sys/isa/atkbd_isa.c b/sys/isa/atkbd_isa.c
index ade1ba0..1d7ee62 100644
--- a/sys/isa/atkbd_isa.c
+++ b/sys/isa/atkbd_isa.c
@@ -23,7 +23,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: atkbd_isa.c,v 1.1 1999/01/23 16:53:27 dfr Exp $
+ * $Id: atkbd_isa.c,v 1.2 1999/03/10 10:36:49 yokota Exp $
*/
#include "atkbd.h"
@@ -37,6 +37,7 @@
#include <sys/conf.h>
#include <sys/tty.h>
#include <sys/bus.h>
+#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
@@ -70,9 +71,9 @@ static driver_t atkbd_driver = {
static int
atkbdprobe(device_t dev)
{
- u_long port;
- u_long irq;
- u_long flags;
+ uintptr_t port;
+ uintptr_t irq;
+ uintptr_t flags;
device_set_desc(dev, "AT Keyboard");
@@ -89,9 +90,9 @@ static int
atkbdattach(device_t dev)
{
atkbd_softc_t *sc;
- u_long port;
- u_long irq;
- u_long flags;
+ uintptr_t port;
+ uintptr_t irq;
+ uintptr_t flags;
struct resource *res;
void *ih;
int zero = 0;
diff --git a/sys/isa/fd.c b/sys/isa/fd.c
index 07223f1..0414b18 100644
--- a/sys/isa/fd.c
+++ b/sys/isa/fd.c
@@ -47,7 +47,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.133 1999/02/10 00:03:32 ken Exp $
+ * $Id: fd.c,v 1.134 1999/04/06 03:06:51 peter Exp $
*
*/
@@ -60,26 +60,37 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
#include <sys/conf.h>
-#include <sys/fcntl.h>
-#include <machine/clock.h>
-#include <machine/ioctl_fd.h>
#include <sys/disklabel.h>
-#include <sys/buf.h>
#include <sys/devicestat.h>
+#include <sys/fcntl.h>
#include <sys/malloc.h>
+#include <sys/module.h>
#include <sys/proc.h>
#include <sys/syslog.h>
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/fdreg.h>
-#include <i386/isa/fdc.h>
-#include <i386/isa/rtc.h>
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+
+#include <machine/clock.h>
+#include <machine/ioctl_fd.h>
+#include <machine/resource.h>
#include <machine/stdarg.h>
+
#ifdef DEVFS
#include <sys/devfsext.h>
#endif /* DEVFS */
+#include <isa/isavar.h>
+#include <i386/isa/isa.h>
+#include <i386/isa/isa_dma.h>
+#include <i386/isa/fdreg.h>
+#include <i386/isa/fdc.h>
+#include <i386/isa/rtc.h>
+
/* misuse a flag to identify format operation */
#define B_FORMAT B_XXX
@@ -151,13 +162,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...) */
@@ -179,7 +190,10 @@ static struct fd_data {
void *bdevs[1 + NUMDENS + MAXPARTITIONS];
void *cdevs[1 + NUMDENS + MAXPARTITIONS];
#endif
-} fd_data[NFD];
+ device_t dev;
+ fdu_t fdu;
+};
+static devclass_t fd_devclass;
/***********************************************************************\
* Throughout this file the following conventions will be used: *
@@ -195,29 +209,26 @@ static struct fd_data {
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);
@@ -356,13 +367,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;
@@ -374,28 +378,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;
@@ -407,9 +401,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;
@@ -422,26 +415,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);
}
}
@@ -462,8 +455,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;
@@ -474,17 +467,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;
}
@@ -493,9 +486,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;
@@ -506,13 +499,11 @@ 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;
- 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;
}
@@ -520,17 +511,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)
@@ -545,8 +534,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
@@ -554,7 +542,7 @@ fd_read_status(fdc_p fdc, int fdsu)
*/
int status;
- ret = fd_in(fdc->fdcu, &status);
+ ret = fd_in(fdc, &status);
fdc->status[i] = status;
if (ret != 0)
break;
@@ -572,34 +560,92 @@ fd_read_status(fdc_p fdc, int fdsu)
/* autoconfiguration stuff */
/****************************************************************************/
-/*
- * 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);
/* 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);
/* see if it can handle a command */
- if (fd_cmd(fdcu,
- 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240), NE7_SPEC_2(2, 0),
- 0))
- {
- return(0);
+ if (fd_cmd(fdc, 3, NE7CMD_SPECIFY, NE7_SPEC_1(3, 240),
+ NE7_SPEC_2(2, 0), 0)) {
+ error = ENXIO;
+ goto out;
+ }
+
+ 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;
+ }
}
+
+ 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
@@ -608,277 +654,312 @@ 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;
- int fdsu, st0, st3, i;
- struct isa_device *fdup;
- int ic_type = 0;
-#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;
- fdc->dmachan = dev->id_drq;
+
/* 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;
+
/* reset controller, turn motor off, clear fdout mirror reg */
outb(fdc->baseport + FDOUT, ((fdc->fdout = 0)));
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) {
- 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;
- }
- /* is there a unit? */
- if ((fdt == RTCFDT_NONE)
- ) {
- fd->type = NO_TYPE;
- continue;
- }
+#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));
+}
- /* select it */
- set_motor(fdcu, fdsu, TURNON);
- DELAY(1000000); /* 1 sec */
+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));
+}
- 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");
+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
- fdc->fdct = FDC_NE72065;
- break;
- default:
-#ifdef FDC_PRINT_BOGUS_CHIPTYPE
- printf("unknown IC type %02x\n", ic_type);
+
+ 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);
+
+ /* 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;
+ }
+
+ /* is there a unit? */
+ if (fdt == RTCFDT_NONE)
+ return (ENXIO);
+
+ /* 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);
- 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) {
- case RTCFDT_12M:
- printf("1.2MB 5.25in\n");
- fd->type = FD_1200;
- 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;
+ fd->track = FD_NO_TRACK;
+ fd->fdc = fdc;
+ fd->fdsu = fdsu;
+ fd->options = 0;
+ callout_handle_init(&fd->toffhandle);
+ callout_handle_init(&fd->tohandle);
+
+ 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);
+ }
+ return (0);
+}
+
+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.
+ */
+ switch (fd->type) {
+ case FD_360:
+ if (i != FD_360)
+ continue;
break;
- case RTCFDT_288M:
- case RTCFDT_288M_1:
- printf("2.88MB 3.5in - 1.44MB mode\n");
- fd->type = FD_1440;
+ case FD_720:
+ if (i != FD_720 && i != FD_800 && i != FD_820)
+ continue;
break;
- case RTCFDT_360K:
- printf("360KB 5.25in\n");
- fd->type = FD_360;
+ 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_720K:
- printf("720KB 3.5in\n");
- fd->type = FD_720;
+ 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;
- 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.
- */
- 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;
- }
- 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;
- 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 */
+ 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;
+ 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
@@ -1016,9 +1097,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;
if(turnon) {
@@ -1038,83 +1119,78 @@ set_motor(fdcu_t fdcu, int fdsu, int turnon)
fdout |= (FDO_FRST|FDO_FDMAEN);
}
- outb(fdc_data[fdcu].baseport+FDOUT, fdout);
- 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
* from its sleep, we silently assume the command will
* be accepted, and do not test for a timeout
*/
- (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);
- 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 */
outb(fdc->baseport + FDOUT, fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
TRACE1("[0x%x->FDOUT]", fdc->fdout & ~(FDO_FRST|FDO_FDMAEN));
@@ -1127,7 +1203,7 @@ fdc_reset(fdc_p fdc)
TRACE1("[0x%x->FDOUT]", fdc->fdout);
/* XXX after a reset, silently believe the FDC will accept commands */
- (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);
if (fdc->flags & FDC_HAS_FIFO)
@@ -1138,16 +1214,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);
@@ -1161,16 +1237,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);
@@ -1185,21 +1261,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);
@@ -1215,32 +1291,33 @@ 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);
if (type == 0)
- type = fd_data[fdu].type;
+ type = fd->type;
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) {
@@ -1279,9 +1356,10 @@ Fdopen(dev_t dev, int flags, int mode, struct proc *p)
}
}
}
- 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;
}
@@ -1289,11 +1367,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
@@ -1317,16 +1397,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;
@@ -1341,7 +1422,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);
@@ -1386,12 +1467,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;
@@ -1409,27 +1490,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);
/*
@@ -1447,19 +1526,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);
}
@@ -1469,11 +1547,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
@@ -1513,7 +1591,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;
@@ -1537,26 +1615,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;
@@ -1569,8 +1646,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:
@@ -1585,10 +1662,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 *
@@ -1596,12 +1672,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);
}
if (fdc->flags & FDC_NEEDS_RESET) {
fdc->state = RESETCTLR;
@@ -1615,7 +1691,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdc->state = SEEKCOMPLETE;
break;
}
- if (fd_cmd(fdcu, 3, NE7CMD_SEEK,
+ if (fd_cmd(fdc, 3, NE7CMD_SEEK,
fd->fdsu, b_cylinder * fd->ft->steptrac,
0))
{
@@ -1624,20 +1700,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 {
/*
@@ -1669,8 +1744,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
@@ -1685,22 +1759,20 @@ 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));
}
}
- 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));
}
}
@@ -1726,7 +1798,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)
{
@@ -1749,8 +1821,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,
@@ -1758,25 +1829,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) {
/*
@@ -1795,7 +1860,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 */
@@ -1805,14 +1870,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
@@ -1834,8 +1898,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 FDC_YE
case PIOREAD:
/*
@@ -1847,16 +1911,15 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
/* FALLTHROUGH */
#endif
case IOCOMPLETE: /* IO DONE, post-analyze */
- untimeout(fd_iotimeout, (caddr_t)fdcu, fd->tohandle);
+ untimeout(fd_iotimeout, fdc, fd->tohandle);
- 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;
@@ -1869,8 +1932,7 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
#endif
isa_dmadone(bp->b_flags, bp->b_data + fd->skip,
format ? bp->b_bcount : fdblk, fdc->dmachan);
- 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) {
/*
@@ -1890,17 +1952,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;
@@ -1915,7 +1974,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++;
@@ -1931,21 +1990,18 @@ fdstate(fdcu_t fdcu, fdc_p fdc)
fdc->state = STARTRECAL;
/* Fall through. */
case STARTRECAL:
- 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 {
/*
@@ -1971,16 +2027,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;
@@ -1993,9 +2049,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],
@@ -2010,28 +2067,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;
@@ -2084,10 +2144,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
@@ -2104,7 +2164,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() */
@@ -2135,20 +2195,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
@@ -2171,7 +2230,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;
@@ -2181,13 +2240,12 @@ fdioctl(dev, cmd, addr, flag, p)
fdblk = 128 << fd->ft->secsize;
- 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;
@@ -2211,8 +2269,7 @@ fdioctl(dev, cmd, addr, flag, p)
break;
case DIOCWDINFO:
- if ((flag & FWRITE) == 0)
- {
+ if ((flag & FWRITE) == 0) {
error = EBADF;
break;
}
@@ -2227,9 +2284,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
@@ -2242,7 +2299,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;
@@ -2262,22 +2319,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/isa/fdc.h b/sys/isa/fdc.h
index 43bf9f8..83e291f 100644
--- a/sys/isa/fdc.h
+++ b/sys/isa/fdc.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fdc.h,v 1.12 1998/12/12 08:16:01 imp Exp $
+ * $Id: fdc.h,v 1.13 1999/01/15 09:15:27 bde Exp $
*
*/
@@ -70,6 +70,10 @@ struct fdc_data
int fdc_errs; /* number of logged errors */
struct buf_queue_head head;
struct buf *bp; /* active buffer */
+ struct resource *res_ioport, *res_irq, *res_drq;
+ int rid_ioport, rid_irq, rid_drq;
+ void *fdc_intr;
+ struct device *fdc_dev;
};
/***********************************************************************\
diff --git a/sys/isa/isavar.h b/sys/isa/isavar.h
index bb8ee55..21447b6 100644
--- a/sys/isa/isavar.h
+++ b/sys/isa/isavar.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: isavar.h,v 1.1 1998/08/06 08:49:09 dfr Exp $
+ * $Id: isavar.h,v 1.2 1998/11/15 18:25:17 dfr Exp $
*/
#define ISA_NPORT_IVARS 2
@@ -63,7 +63,7 @@ extern int isa_irq_mask(void);
\
static __inline T isa_get_ ## A(device_t dev) \
{ \
- u_long v; \
+ uintptr_t v; \
BUS_READ_IVAR(device_get_parent(dev), dev, ISA_IVAR_ ## B, &v); \
return (T) v; \
} \
@@ -78,4 +78,7 @@ ISA_ACCESSOR(port, PORT, int)
ISA_ACCESSOR(portsize, PORTSIZE, int)
ISA_ACCESSOR(flags, FLAGS, int)
ISA_ACCESSOR(irq, IRQ, int)
+ISA_ACCESSOR(drq, DRQ, int)
+ISA_ACCESSOR(maddr, MADDR, int)
+ISA_ACCESSOR(msize, MSIZE, int)
diff --git a/sys/isa/psm.c b/sys/isa/psm.c
index e7eb469..b3dc1d0 100644
--- a/sys/isa/psm.c
+++ b/sys/isa/psm.c
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: psm.c,v 1.2 1998/11/15 18:25:17 dfr Exp $
+ * $Id: psm.c,v 1.3 1999/01/23 16:53:28 dfr Exp $
*/
/*
@@ -76,6 +76,7 @@
#include <sys/poll.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
+#include <machine/bus.h>
#include <sys/rman.h>
#ifdef DEVFS
#include <sys/devfsext.h>
@@ -740,8 +741,8 @@ psmprobe(device_t dev)
{
int unit = device_get_unit(dev);
struct psm_softc *sc = device_get_softc(dev);
- u_long port;
- u_long flags;
+ uintptr_t port;
+ uintptr_t flags;
int stat[3];
int command_byte;
int mask;
@@ -991,7 +992,7 @@ psmattach(device_t dev)
struct psm_softc *sc = device_get_softc(dev);
void *ih;
struct resource *res;
- u_long irq;
+ uintptr_t irq;
int zero = 0;
if (sc == NULL) /* shouldn't happen */
diff --git a/sys/isa/sio.c b/sys/isa/sio.c
index ee031b4..1a40360 100644
--- a/sys/isa/sio.c
+++ b/sys/isa/sio.c
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sio.c,v 1.220 1999/01/19 00:21:47 peter Exp $
+ * $Id: sio.c,v 1.221 1999/01/30 12:17:35 phk Exp $
* from: @(#)com.c 7.5 (Berkeley) 5/16/91
* from: i386/isa sio.c,v 1.215
*/
@@ -68,6 +68,7 @@
#include <sys/syslog.h>
#include <sys/sysctl.h>
#include <sys/bus.h>
+#include <machine/bus.h>
#include <sys/rman.h>
#ifdef DEVFS
#include <sys/devfsext.h>
@@ -103,8 +104,10 @@
#endif
+#ifndef __i386__
#define disable_intr() 0
#define enable_intr() 0
+#endif
#ifdef SMP
#define disable_intr() COM_DISABLE_INTR()
@@ -2607,6 +2610,21 @@ 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.
+ */
+static cn_probe_t siocnprobe;
+static cn_init_t siocninit;
+static cn_checkc_t siocncheckc;
+ cn_getc_t siocngetc;
+ cn_putc_t siocnputc;
+
+CONS_DRIVER(sio, siocnprobe, siocninit, siocngetc, siocncheckc, siocnputc);
+
+#endif
+
static void
siocntxwait(iobase)
Port_t iobase;
@@ -2731,11 +2749,9 @@ void
siocnprobe(cp)
struct consdev *cp;
{
-#if 0
speed_t boot_speed;
u_char cfcr;
- struct isa_device *dvp;
- int s;
+ int s, unit;
struct siocnstate sp;
/*
@@ -2753,10 +2769,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,
@@ -2784,17 +2806,19 @@ siocnprobe(cp)
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;
}
-#endif
+ }
}
+#ifdef __alpha__
+
struct consdev siocons = {
NULL, NULL, siocngetc, siocncheckc, siocnputc,
NULL, makedev(CDEV_MAJOR, 0), CN_NORMAL,
@@ -2877,6 +2901,8 @@ siogdbattach(port, speed)
return 0;
}
+#endif
+
void
siocninit(cp)
struct consdev *cp;
@@ -3158,7 +3184,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;
@@ -3180,9 +3205,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)
diff --git a/sys/isa/syscons_isa.c b/sys/isa/syscons_isa.c
index 9f61cec..e837cab 100644
--- a/sys/isa/syscons_isa.c
+++ b/sys/isa/syscons_isa.c
@@ -23,7 +23,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:$
+ * $Id: syscons_isa.c,v 1.1 1999/01/23 16:53:30 dfr Exp $
*/
#include "sc.h"
@@ -38,6 +38,9 @@
#include <sys/bus.h>
#include <machine/console.h>
+#ifdef __i386__
+#include <machine/apm_bios.h>
+#endif
#include <dev/syscons/syscons.h>
diff --git a/sys/isa/vga_isa.c b/sys/isa/vga_isa.c
index 49baedb..b5e4903 100644
--- a/sys/isa/vga_isa.c
+++ b/sys/isa/vga_isa.c
@@ -26,7 +26,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: vga_isa.c,v 1.2 1999/02/05 11:52:08 yokota Exp $
+ * $Id: vga_isa.c,v 1.3 1999/02/05 12:58:32 yokota Exp $
*/
#include "vga.h"
@@ -52,7 +52,7 @@
#include <dev/fb/fbreg.h>
#include <dev/fb/vgareg.h>
-#ifndef __i386__
+#if 1
#include <isa/isareg.h>
#include <isa/isavar.h>
#else
@@ -71,7 +71,7 @@ typedef struct isavga_softc {
video_adapter_t *adp;
} isavga_softc_t;
-#ifndef __i386__
+#if 1
#define ISAVGA_SOFTC(unit) \
((isavga_softc_t *)devclass_get_softc(isavga_devclass, unit))
@@ -135,7 +135,7 @@ static struct cdevsw vga_cdevsw = {
#endif /* FB_INSTALL_CDEV */
-#ifndef __i386__
+#if 1
static int
isavga_probe(device_t dev)
@@ -776,6 +776,9 @@ verify_adapter(video_adapter_t *adp)
{
vm_offset_t buf;
u_int16_t v;
+#if !defined(VGA_NO_BIOS) && !defined(VGA_NO_MODE_CHANGE)
+ u_int32_t p;
+#endif
buf = BIOS_PADDRTOVADDR(adp->va_window);
v = readw(buf);
@@ -1077,6 +1080,7 @@ probe_adapters(void)
rows_offset = 1;
} else {
/* discard the table if we are not familiar with it... */
+ u_char *mp;
map_mode_table(mode_map, video_mode_ptr, M_VGA_CG320 + 1);
mp = get_mode_param(adp->va_initial_mode);
if (mp != NULL)
@@ -1138,6 +1142,7 @@ probe_adapters(void)
if (video_mode_ptr == NULL) {
rows_offset = 1;
} else {
+ u_char *mp;
map_mode_table(mode_map, video_mode_ptr, M_ENH_C80x25 + 1);
/* XXX how can one validate the EGA table... */
mp = get_mode_param(adp->va_initial_mode);
diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m
index 8c48082..191906b 100644
--- a/sys/kern/bus_if.m
+++ b/sys/kern/bus_if.m
@@ -23,7 +23,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# $Id: bus_if.m,v 1.5 1998/11/14 21:58:51 wollman Exp $
+# $Id: bus_if.m,v 1.6 1999/03/29 08:54:19 dfr Exp $
#
INTERFACE bus;
@@ -80,6 +80,16 @@ METHOD void child_detached {
};
#
+# Called when a new driver is added to the devclass which owns this
+# bus. The generic implementation of this method attempts to probe and
+# attach any un-matched children of the bus.
+#
+METHOD void driver_added {
+ device_t dev;
+ driver_t *driver;
+}
+
+#
# Allocate a system resource attached to `dev' on behalf of `child'.
# The types are defined in <machine/resource.h>; the meaning of the
# resource-ID field varies from bus to bus (but *rid == 0 is always
diff --git a/sys/kern/makedevops.pl b/sys/kern/makedevops.pl
index 1c434d5..ce428e5 100644
--- a/sys/kern/makedevops.pl
+++ b/sys/kern/makedevops.pl
@@ -323,7 +323,7 @@ foreach $src ( @filenames ) {
if ( $cfile ) {
# Print out the method desc
print CFILE "struct device_op_desc $mname\_desc = {\n";
- print CFILE "\t0, \"$mname\"\n";
+ print CFILE "\t0, 0, \"$mname\"\n";
print CFILE "};\n\n";
# Print out the method itself
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 4469b70..339ef32 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: subr_bus.c,v 1.15 1999/01/27 21:49:57 dillon Exp $
+ * $Id: subr_bus.c,v 1.16 1999/03/29 08:54:20 dfr Exp $
*/
#include <sys/param.h>
@@ -94,50 +94,62 @@ static void device_unregister_oids(device_t dev);
* Method table handling
*/
static int next_method_offset = 1;
-static int methods_count = 0;
-static int methods_size = 0;
+LIST_HEAD(methodlist, method) methods;
struct method {
- int offset;
- char* name;
+ LIST_ENTRY(method) link; /* linked list of methods */
+ int offset; /* offset in method table */
+ int refs; /* count of device_op_desc users */
+ char* name; /* unique name of method */
};
-static struct method *methods = 0;
-
static void
register_method(struct device_op_desc *desc)
{
- int i;
struct method* m;
- for (i = 0; i < methods_count; i++)
- if (!strcmp(methods[i].name, desc->name)) {
- desc->offset = methods[i].offset;
- PDEBUG(("methods[%d] has the same name, %s, with offset %d",
- i, desc->name, desc->offset));
- return;
- }
-
- if (methods_count == methods_size) {
- struct method* p;
+ if (desc->method) {
+ desc->method->refs++;
+ return;
+ }
- methods_size += 10;
- p = (struct method*) malloc(methods_size * sizeof(struct method),
- M_DEVBUF, M_NOWAIT);
- if (!p)
- panic("register_method: out of memory");
- if (methods) {
- bcopy(methods, p, methods_count * sizeof(struct method));
- free(methods, M_DEVBUF);
+ for (m = LIST_FIRST(&methods); m; m = LIST_NEXT(m, link)) {
+ if (!strcmp(m->name, desc->name)) {
+ desc->offset = m->offset;
+ desc->method = m;
+ m->refs++;
+ PDEBUG(("methods %x has the same name, %s, with offset %d",
+ m, desc->name, desc->offset));
+ return;
}
- methods = p;
}
- m = &methods[methods_count++];
- m->name = malloc(strlen(desc->name) + 1, M_DEVBUF, M_NOWAIT);
- if (!m->name)
+
+ m = (struct method *) malloc(sizeof(struct method)
+ + strlen(desc->name) + 1,
+ M_DEVBUF, M_NOWAIT);
+ if (!m)
panic("register_method: out of memory");
+ bzero(m, sizeof(struct method) + strlen(desc->name) + 1);
+ m->offset = next_method_offset++;
+ m->refs = 1;
+ m->name = (char*) (m + 1);
strcpy(m->name, desc->name);
- desc->offset = m->offset = next_method_offset++;
+ LIST_INSERT_HEAD(&methods, m, link);
+
+ desc->offset = m->offset;
+ desc->method = m;
+}
+
+static void
+unregister_method(struct device_op_desc *desc)
+{
+ struct method *m = desc->method;
+ m->refs--;
+ if (m->refs == 0) {
+ LIST_REMOVE(m, link);
+ free(m, M_DEVBUF);
+ }
+ desc->method = 0;
}
static int error_method(void)
@@ -161,10 +173,7 @@ compile_methods(driver_t *driver)
* First register any methods which need it.
*/
for (i = 0, m = driver->methods; m->desc; i++, m++)
- if (!m->desc->offset)
- register_method(m->desc);
- else
- PDEBUG(("offset not equal to zero, method desc %d left as is", i));
+ register_method(m->desc);
/*
* Then allocate the compiled op table.
@@ -173,6 +182,7 @@ compile_methods(driver_t *driver)
M_DEVBUF, M_NOWAIT);
if (!ops)
panic("compile_methods: out of memory");
+ bzero(ops, sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t));
ops->maxoffset = next_method_offset;
for (i = 0; i < next_method_offset; i++)
@@ -186,6 +196,25 @@ compile_methods(driver_t *driver)
driver->ops = ops;
}
+static void
+free_methods(driver_t *driver)
+{
+ int i;
+ struct device_method *m;
+
+ /*
+ * Unregister any methods which are no longer used.
+ */
+ for (i = 0, m = driver->methods; m->desc; i++, m++)
+ unregister_method(m->desc);
+
+ /*
+ * Free memory and clean up.
+ */
+ free(driver->ops, M_DEVBUF);
+ driver->ops = 0;
+}
+
/*
* Devclass implementation
*/
@@ -211,6 +240,7 @@ devclass_find_internal(const char *classname, int create)
M_DEVBUF, M_NOWAIT);
if (!dc)
return NULL;
+ bzero(dc, sizeof(struct devclass) + strlen(classname) + 1);
dc->name = (char*) (dc + 1);
strcpy(dc->name, classname);
dc->devices = NULL;
@@ -233,17 +263,20 @@ int
devclass_add_driver(devclass_t dc, driver_t *driver)
{
driverlink_t dl;
+ int i;
PDEBUG(("%s", DRIVERNAME(driver)));
dl = malloc(sizeof *dl, M_DEVBUF, M_NOWAIT);
if (!dl)
return ENOMEM;
+ bzero(dl, sizeof *dl);
/*
- * Compile the drivers methods.
+ * Compile the driver's methods.
*/
- compile_methods(driver);
+ if (!driver->ops)
+ compile_methods(driver);
/*
* Make sure the devclass which the driver is implementing exists.
@@ -252,6 +285,14 @@ devclass_add_driver(devclass_t dc, driver_t *driver)
dl->driver = driver;
TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
+ driver->refs++;
+
+ /*
+ * Call BUS_DRIVER_ADDED for any existing busses in this class.
+ */
+ for (i = 0; i < dc->maxunit; i++)
+ if (dc->devices[i])
+ BUS_DRIVER_ADDED(dc->devices[i], driver);
return 0;
}
@@ -309,6 +350,10 @@ devclass_delete_driver(devclass_t busclass, driver_t *driver)
TAILQ_REMOVE(&busclass->drivers, dl, link);
free(dl, M_DEVBUF);
+ driver->refs--;
+ if (driver->refs == 0)
+ free_methods(driver);
+
return 0;
}
@@ -382,6 +427,7 @@ devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp)
list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
if (!list)
return ENOMEM;
+ bzero(list, count * sizeof(device_t));
count = 0;
for (i = 0; i < dc->maxunit; i++)
@@ -462,6 +508,7 @@ devclass_add_device(devclass_t dc, device_t dev)
dev->nameunit = malloc(buflen, M_DEVBUF, M_NOWAIT);
if (!dev->nameunit)
return ENOMEM;
+ bzero(dev->nameunit, buflen);
if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) {
free(dev->nameunit, M_DEVBUF);
@@ -528,6 +575,7 @@ make_device(device_t parent, const char *name,
dev = malloc(sizeof(struct device), M_DEVBUF, M_NOWAIT);
if (!dev)
return 0;
+ bzero(dev, sizeof(struct device));
dev->parent = parent;
TAILQ_INIT(&dev->children);
@@ -721,6 +769,7 @@ device_get_children(device_t dev, device_t **devlistp, int *devcountp)
list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
if (!list)
return ENOMEM;
+ bzero(list, count * sizeof(device_t));
count = 0;
for (child = TAILQ_FIRST(&dev->children); child;
@@ -1146,12 +1195,69 @@ device_unregister_oids(device_t dev)
#endif
+/*======================================*/
/*
* Access functions for device resources.
*/
-extern struct config_device devtab[];
+
+/* Supplied by config(8) in ioconf.c */
+extern struct config_device config_devtab[];
extern int devtab_count;
+/* Runtime version */
+struct config_device *devtab = config_devtab;
+
+static int
+resource_new_name(char *name, int unit)
+{
+ struct config_device *new;
+
+ new = malloc((devtab_count + 1) * sizeof(*new), M_TEMP, M_NOWAIT);
+ if (new == NULL)
+ return -1;
+ if (devtab && devtab_count > 0)
+ bcopy(devtab, new, devtab_count * sizeof(*new));
+ bzero(&new[devtab_count], sizeof(*new));
+ new[devtab_count].name = malloc(strlen(name) + 1, M_TEMP, M_NOWAIT);
+ if (new[devtab_count].name == NULL) {
+ free(new, M_TEMP);
+ return -1;
+ }
+ strcpy(new[devtab_count].name, name);
+ new[devtab_count].unit = unit;
+ new[devtab_count].resource_count = 0;
+ new[devtab_count].resources = NULL;
+ devtab = new;
+ return devtab_count++;
+}
+
+static int
+resource_new_resname(int j, char *resname, resource_type type)
+{
+ struct config_resource *new;
+ int i;
+
+ i = devtab[j].resource_count;
+ new = malloc((i + 1) * sizeof(*new), M_TEMP, M_NOWAIT);
+ if (new == NULL)
+ return -1;
+ if (devtab[j].resources && i > 0)
+ bcopy(devtab[j].resources, new, i * sizeof(*new));
+ bzero(&new[i], sizeof(*new));
+ new[i].name = malloc(strlen(resname) + 1, M_TEMP, M_NOWAIT);
+ if (new[i].name == NULL) {
+ free(new, M_TEMP);
+ return -1;
+ }
+ strcpy(new[i].name, resname);
+ new[i].type = type;
+ if (devtab[j].resources)
+ free(devtab[j].resources, M_TEMP);
+ devtab[j].resources = new;
+ devtab[j].resource_count = i + 1;
+ return i;
+}
+
static int
resource_match_string(int i, char *resname, char *value)
{
@@ -1163,8 +1269,8 @@ resource_match_string(int i, char *resname, char *value)
if (!strcmp(res->name, resname)
&& res->type == RES_STRING
&& !strcmp(res->u.stringval, value))
- return TRUE;
- return FALSE;
+ return j;
+ return -1;
}
static int
@@ -1209,6 +1315,7 @@ resource_int_value(const char *name, int unit, char *resname, int *result)
{
int error;
struct config_resource *res;
+
if ((error = resource_find(name, unit, resname, &res)) != 0)
return error;
if (res->type != RES_INT)
@@ -1222,6 +1329,7 @@ resource_long_value(const char *name, int unit, char *resname, long *result)
{
int error;
struct config_resource *res;
+
if ((error = resource_find(name, unit, resname, &res)) != 0)
return error;
if (res->type != RES_LONG)
@@ -1235,6 +1343,7 @@ resource_string_value(const char *name, int unit, char *resname, char **result)
{
int error;
struct config_resource *res;
+
if ((error = resource_find(name, unit, resname, &res)) != 0)
return error;
if (res->type != RES_STRING)
@@ -1251,11 +1360,30 @@ resource_query_string(int i, char *resname, char *value)
else
i = i + 1;
for (; i < devtab_count; i++)
- if (resource_match_string(i, resname, value))
+ if (resource_match_string(i, resname, value) >= 0)
return i;
return -1;
}
+int
+resource_locate(int i, char *resname)
+{
+ if (i < 0)
+ i = 0;
+ else
+ i = i + 1;
+ for (; i < devtab_count; i++)
+ if (!strcmp(devtab[i].name, resname))
+ return i;
+ return -1;
+}
+
+int
+resource_count(void)
+{
+ return devtab_count;
+}
+
char *
resource_query_name(int i)
{
@@ -1268,7 +1396,165 @@ resource_query_unit(int i)
return devtab[i].unit;
}
+static int
+resource_create(char *name, int unit, char *resname, resource_type type,
+ struct config_resource **result)
+{
+ int i, j;
+ struct config_resource *res = NULL;
+
+ for (i = 0; i < devtab_count; i++) {
+ if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
+ res = devtab[i].resources;
+ break;
+ }
+ }
+ if (res == NULL) {
+ i = resource_new_name(name, unit);
+ if (i < 0)
+ return ENOMEM;
+ res = devtab[i].resources;
+ }
+ for (j = 0; j < devtab[i].resource_count; j++, res++) {
+ if (!strcmp(res->name, resname)) {
+ *result = res;
+ return 0;
+ }
+ }
+ j = resource_new_resname(i, resname, type);
+ if (j < 0)
+ return ENOMEM;
+ res = &devtab[i].resources[j];
+ *result = res;
+ return 0;
+}
+
+int
+resource_set_int(int i, char *resname, int value)
+{
+ int error;
+ struct config_resource *res;
+printf("resource_set_int\n");
+ if (i < 0 || i >= devtab_count)
+ return EINVAL;
+ error = resource_create(devtab[i].name, devtab[i].unit, resname,
+ RES_INT, &res);
+ if (error)
+ return error;
+ if (res->type != RES_INT)
+ return EFTYPE;
+ res->u.intval = value;
+ return 0;
+}
+
+int
+resource_set_long(int i, char *resname, long value)
+{
+ int error;
+ struct config_resource *res;
+
+printf("resource_set_long\n");
+ if (i < 0 || i >= devtab_count)
+ return EINVAL;
+ error = resource_create(devtab[i].name, devtab[i].unit, resname,
+ RES_LONG, &res);
+ if (error)
+ return error;
+ if (res->type != RES_LONG)
+ return EFTYPE;
+ res->u.longval = value;
+ return 0;
+}
+
+int
+resource_set_string(int i, char *resname, char *value)
+{
+ int error;
+ struct config_resource *res;
+
+printf("resource_set_string\n");
+ if (i < 0 || i >= devtab_count)
+ return EINVAL;
+ error = resource_create(devtab[i].name, devtab[i].unit, resname,
+ RES_STRING, &res);
+ if (error)
+ return error;
+ if (res->type != RES_STRING)
+ return EFTYPE;
+ if (res->u.stringval)
+ free(res->u.stringval, M_TEMP);
+ res->u.stringval = malloc(strlen(value) + 1, M_TEMP, M_NOWAIT);
+ if (res->u.stringval == NULL)
+ return ENOMEM;
+ strcpy(res->u.stringval, value);
+ return 0;
+}
+
+
+static void
+resource_cfgload(void *dummy __unused)
+{
+ struct config_resource *res, *cfgres;
+ int i, j;
+ int error;
+ char *name, *resname;
+ int unit;
+ resource_type type;
+ char *stringval;
+ int config_devtab_count;
+
+ config_devtab_count = devtab_count;
+ devtab = NULL;
+ devtab_count = 0;
+
+ for (i = 0; i < config_devtab_count; i++) {
+ name = config_devtab[i].name;
+ unit = config_devtab[i].unit;
+
+ for (j = 0; j < config_devtab[i].resource_count; j++) {
+ cfgres = config_devtab[i].resources;
+ resname = cfgres[j].name;
+ type = cfgres[j].type;
+ error = resource_create(name, unit, resname, type,
+ &res);
+ if (error) {
+ printf("create resource %s%d: error %d\n",
+ name, unit, error);
+ continue;
+ }
+ if (res->type != type) {
+ printf("type mismatch %s%d: %d != %d\n",
+ name, unit, res->type, type);
+ continue;
+ }
+ switch (type) {
+ case RES_INT:
+ res->u.intval = cfgres[j].u.intval;
+ break;
+ case RES_LONG:
+ res->u.longval = cfgres[j].u.longval;
+ break;
+ case RES_STRING:
+ if (res->u.stringval)
+ free(res->u.stringval, M_TEMP);
+ stringval = cfgres[j].u.stringval;
+ res->u.stringval = malloc(strlen(stringval) + 1,
+ M_TEMP, M_NOWAIT);
+ if (res->u.stringval == NULL)
+ break;
+ strcpy(res->u.stringval, stringval);
+ break;
+ default:
+ panic("unknown resource type %d\n", type);
+ }
+ }
+ }
+}
+SYSINIT(cfgload, SI_SUB_KMEM, SI_ORDER_ANY + 50, resource_cfgload, 0)
+
+
+/*======================================*/
/*
* Some useful method implementations to make life easier for bus drivers.
*/
@@ -1308,7 +1594,7 @@ bus_generic_shutdown(device_t dev)
for (child = TAILQ_FIRST(&dev->children);
child; child = TAILQ_NEXT(child, link))
- DEVICE_SHUTDOWN(child);
+ device_shutdown(child);
return 0;
}
@@ -1366,6 +1652,17 @@ bus_generic_write_ivar(device_t dev, device_t child, int index,
return ENOENT;
}
+void
+bus_generic_driver_added(device_t dev, driver_t *driver)
+{
+ device_t child;
+
+ for (child = TAILQ_FIRST(&dev->children);
+ child; child = TAILQ_NEXT(child, link))
+ if (child->state == DS_NOTPRESENT)
+ device_probe_and_attach(child);
+}
+
int
bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
driver_intr_t *intr, void *arg, void **cookiep)
@@ -1513,6 +1810,7 @@ root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg,
static device_method_t root_methods[] = {
/* Device interface */
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
@@ -1548,6 +1846,10 @@ root_bus_module_handler(module_t mod, int what, void* arg)
root_bus->state = DS_ATTACHED;
root_devclass = devclass_find_internal("root", FALSE);
return 0;
+
+ case MOD_SHUTDOWN:
+ device_shutdown(root_bus);
+ return 0;
}
return 0;
diff --git a/sys/kern/subr_rman.c b/sys/kern/subr_rman.c
index fee2e2a..a043230 100644
--- a/sys/kern/subr_rman.c
+++ b/sys/kern/subr_rman.c
@@ -26,7 +26,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: subr_rman.c,v 1.5 1999/03/29 08:30:17 dfr Exp $
+ * $Id: subr_rman.c,v 1.6 1999/04/11 02:27:06 eivind Exp $
*/
/*
@@ -62,8 +62,9 @@
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
-#include <sys/rman.h>
#include <sys/bus.h> /* XXX debugging */
+#include <machine/bus.h>
+#include <sys/rman.h>
static MALLOC_DEFINE(M_RMAN, "rman", "Resource manager");
@@ -73,6 +74,7 @@ static struct simplelock rman_lock; /* mutex to protect rman_head */
#endif
static int int_rman_activate_resource(struct rman *rm, struct resource *r,
struct resource **whohas);
+static int int_rman_deactivate_resource(struct resource *r);
static int int_rman_release_resource(struct rman *rm, struct resource *r);
#define CIRCLEQ_TERMCOND(var, head) (var == (void *)&(head))
@@ -117,6 +119,7 @@ rman_manage_region(struct rman *rm, u_long start, u_long end)
r = malloc(sizeof *r, M_RMAN, M_NOWAIT);
if (r == 0)
return ENOMEM;
+ bzero(r, sizeof *r);
r->r_sharehead = 0;
r->r_start = start;
r->r_end = end;
@@ -148,8 +151,10 @@ rman_fini(struct rman *rm)
simple_lock(rm->rm_slock);
for (r = rm->rm_list.cqh_first; !CIRCLEQ_TERMCOND(r, rm->rm_list);
r = r->r_link.cqe_next) {
- if (r->r_flags & RF_ALLOCATED)
+ if (r->r_flags & RF_ALLOCATED) {
+ simple_unlock(rm->rm_slock);
return EBUSY;
+ }
}
/*
@@ -254,14 +259,16 @@ rman_reserve_resource(struct rman *rm, u_long start, u_long end, u_long count,
* split it in two. The first case requires
* two new allocations; the second requires but one.
*/
- rv = malloc(sizeof *r, M_RMAN, M_NOWAIT);
+ rv = malloc(sizeof *rv, M_RMAN, M_NOWAIT);
if (rv == 0)
goto out;
+ bzero(rv, sizeof *rv);
rv->r_start = rstart;
rv->r_end = rstart + count - 1;
rv->r_flags = flags | RF_ALLOCATED;
rv->r_dev = dev;
rv->r_sharehead = 0;
+ rv->r_rm = rm;
if (s->r_start < rv->r_start && s->r_end > rv->r_end) {
#ifdef RMAN_DEBUG
@@ -280,11 +287,13 @@ rman_reserve_resource(struct rman *rm, u_long start, u_long end, u_long count,
rv = 0;
goto out;
}
+ bzero(r, sizeof *r);
r->r_start = rv->r_end + 1;
r->r_end = s->r_end;
r->r_flags = s->r_flags;
r->r_dev = 0;
r->r_sharehead = 0;
+ r->r_rm = rm;
s->r_end = rv->r_start - 1;
CIRCLEQ_INSERT_AFTER(&rm->rm_list, s, rv,
r_link);
@@ -342,6 +351,7 @@ rman_reserve_resource(struct rman *rm, u_long start, u_long end, u_long count,
rv = malloc(sizeof *rv, M_RMAN, M_NOWAIT);
if (rv == 0)
goto out;
+ bzero(rv, sizeof *rv);
rv->r_start = s->r_start;
rv->r_end = s->r_end;
rv->r_flags = s->r_flags &
@@ -356,6 +366,7 @@ rman_reserve_resource(struct rman *rm, u_long start, u_long end, u_long count,
rv = 0;
goto out;
}
+ bzero(s->r_sharehead, sizeof *s->r_sharehead);
LIST_INIT(s->r_sharehead);
LIST_INSERT_HEAD(s->r_sharehead, s,
r_sharelink);
@@ -451,7 +462,7 @@ rman_await_resource(struct resource *r, int pri, int timo)
simple_lock(rm->rm_slock);
rv = int_rman_activate_resource(rm, r, &whohas);
if (rv != EBUSY)
- return (rv);
+ return (rv); /* returns with simplelock */
if (r->r_sharehead == 0)
panic("rman_await_resource");
@@ -474,18 +485,28 @@ rman_await_resource(struct resource *r, int pri, int timo)
}
}
-int
-rman_deactivate_resource(struct resource *r)
+static int
+int_rman_deactivate_resource(struct resource *r)
{
struct rman *rm;
rm = r->r_rm;
- simple_lock(rm->rm_slock);
r->r_flags &= ~RF_ACTIVE;
if (r->r_flags & RF_WANTED) {
r->r_flags &= ~RF_WANTED;
wakeup(r->r_sharehead);
}
+ return 0;
+}
+
+int
+rman_deactivate_resource(struct resource *r)
+{
+ struct rman *rm;
+
+ rm = r->r_rm;
+ simple_lock(rm->rm_slock);
+ int_rman_deactivate_resource(r);
simple_unlock(rm->rm_slock);
return 0;
}
@@ -496,7 +517,7 @@ int_rman_release_resource(struct rman *rm, struct resource *r)
struct resource *s, *t;
if (r->r_flags & RF_ACTIVE)
- return EBUSY;
+ int_rman_deactivate_resource(r);
/*
* Check for a sharing list first. If there is one, then we don't
diff --git a/sys/net/if.c b/sys/net/if.c
index 680bbd4..635be7d 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)if.c 8.3 (Berkeley) 1/4/94
- * $Id: if.c,v 1.65 1999/02/01 20:03:27 phk Exp $
+ * $Id: if.c,v 1.66 1999/02/19 13:41:35 phk Exp $
*/
#include "opt_compat.h"
@@ -178,6 +178,39 @@ if_attach(ifp)
TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link);
}
}
+
+/*
+ * Detach an interface, removing it from the
+ * list of "active" interfaces.
+ */
+void
+if_detach(ifp)
+ struct ifnet *ifp;
+{
+ struct ifaddr *ifa;
+
+ /*
+ * Remove routes and flush queues.
+ */
+ if_down(ifp);
+
+ /*
+ * Remove address from ifnet_addrs[] and maybe decrement if_index.
+ * Clean up all addresses.
+ */
+ ifnet_addrs[ifp->if_index] = 0;
+ while (ifnet_addrs[if_index] == 0)
+ if_index--;
+
+ for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa;
+ ifa = TAILQ_FIRST(&ifp->if_addrhead)) {
+ TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link);
+ IFAFREE(ifa);
+ }
+
+ TAILQ_REMOVE(&ifnet, ifp, if_link);
+}
+
/*
* Locate an interface based on a complete address.
*/
diff --git a/sys/net/if_media.c b/sys/net/if_media.c
index ee12880..553af92 100644
--- a/sys/net/if_media.c
+++ b/sys/net/if_media.c
@@ -1,5 +1,5 @@
/* $NetBSD: if_media.c,v 1.1 1997/03/17 02:55:15 thorpej Exp $ */
-/* $Id: if_media.c,v 1.5 1998/02/06 12:13:48 eivind Exp $ */
+/* $Id: if_media.c,v 1.6 1998/02/09 06:09:54 eivind Exp $ */
/*
* Copyright (c) 1997
@@ -89,6 +89,19 @@ ifmedia_init(ifm, dontcare_mask, change_callback, status_callback)
ifm->ifm_status = status_callback;
}
+void
+ifmedia_removeall(ifm)
+ struct ifmedia *ifm;
+{
+ struct ifmedia_entry *entry;
+
+ for (entry = LIST_FIRST(&ifm->ifm_list); entry;
+ entry = LIST_FIRST(&ifm->ifm_list)) {
+ LIST_REMOVE(entry, ifm_list);
+ free(entry, M_IFADDR);
+ }
+}
+
/*
* Add a media configuration to the list of supported media
* for a specific interface instance.
diff --git a/sys/net/if_media.h b/sys/net/if_media.h
index c66fd9e..e363485 100644
--- a/sys/net/if_media.h
+++ b/sys/net/if_media.h
@@ -1,5 +1,5 @@
/* $NetBSD: if_media.h,v 1.3 1997/03/26 01:19:27 thorpej Exp $ */
-/* $Id: if_media.h,v 1.3 1999/02/20 11:17:59 julian Exp $ */
+/* $Id: if_media.h,v 1.5 1999/03/07 04:39:25 wpaul Exp $ */
/*
* Copyright (c) 1997
@@ -87,6 +87,9 @@ struct ifmedia {
void ifmedia_init __P((struct ifmedia *ifm, int dontcare_mask,
ifm_change_cb_t change_callback, ifm_stat_cb_t status_callback));
+/* Remove all mediums from a struct ifmedia. */
+void ifmedia_removeall __P(( struct ifmedia *ifm));
+
/* Add one supported medium to a struct ifmedia. */
void ifmedia_add __P((struct ifmedia *ifm, int mword, int data, void *aux));
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 31ce8f6..d66aeb7 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* From: @(#)if.h 8.1 (Berkeley) 6/10/93
- * $Id: if_var.h,v 1.9 1998/06/12 03:48:09 julian Exp $
+ * $Id: if_var.h,v 1.10 1998/12/16 18:30:43 phk Exp $
*/
#ifndef _NET_IF_VAR_H_
@@ -299,6 +299,7 @@ int if_addmulti __P((struct ifnet *, struct sockaddr *,
int if_allmulti __P((struct ifnet *, int));
void if_attach __P((struct ifnet *));
int if_delmulti __P((struct ifnet *, struct sockaddr *));
+void if_detach __P((struct ifnet *));
void if_down __P((struct ifnet *));
void if_route __P((struct ifnet *, int flag, int fam));
void if_unroute __P((struct ifnet *, int flag, int fam));
diff --git a/sys/pci/ide_pci.c b/sys/pci/ide_pci.c
index 524b873..6faef01 100644
--- a/sys/pci/ide_pci.c
+++ b/sys/pci/ide_pci.c
@@ -26,7 +26,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: ide_pci.c,v 1.30 1999/04/13 19:38:12 peter Exp $
+ * $Id: ide_pci.c,v 1.31 1999/04/13 20:22:33 peter Exp $
*/
#include "pci.h"
@@ -1514,6 +1514,7 @@ ide_pci_attach(pcici_t tag, int unit)
wddma[unit].wdd_iobase = ide_pci_iobase;
wddma[unit].wdd_altiobase = ide_pci_altiobase;
+#if 0
/*
* This code below is mighty bogus. The config entries for the
* isa_devtab_bio are plugged in before the standard ISA bios scan.
@@ -1582,7 +1583,7 @@ ide_pci_attach(pcici_t tag, int unit)
}
}
}
-
+#endif
bmista_1 = inb(iobase_bm_1 + BMISTA_PORT);
bmista_2 = inb(iobase_bm_2 + BMISTA_PORT);
diff --git a/sys/pci/if_fxp.c b/sys/pci/if_fxp.c
index 77f0ade..53b8d4d 100644
--- a/sys/pci/if_fxp.c
+++ b/sys/pci/if_fxp.c
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_fxp.c,v 1.65 1999/03/17 16:44:53 luigi Exp $
+ * $Id: if_fxp.c,v 1.66 1999/03/20 04:51:25 wes Exp $
*/
/*
@@ -89,6 +89,10 @@
#else /* __FreeBSD__ */
#include <sys/sockio.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
#include <net/ethernet.h>
#include <net/if_arp.h>
@@ -491,51 +495,31 @@ fxp_ether_ioctl(ifp, cmd, data)
#else /* __FreeBSD__ */
-static u_long fxp_count;
-static const char *fxp_probe __P((pcici_t, pcidi_t));
-static void fxp_attach __P((pcici_t, int));
-
-static void fxp_shutdown __P((int, void *));
-
-static struct pci_device fxp_device = {
- "fxp",
- fxp_probe,
- fxp_attach,
- &fxp_count,
- NULL
-};
-DATA_SET(pcidevice_set, fxp_device);
-
/*
* Return identification string if this is device is ours.
*/
-static const char *
-fxp_probe(config_id, device_id)
- pcici_t config_id;
- pcidi_t device_id;
+static int
+fxp_probe(device_t dev)
{
- if (((device_id & 0xffff) == FXP_VENDORID_INTEL) &&
- ((device_id >> 16) & 0xffff) == FXP_DEVICEID_i82557)
- return ("Intel EtherExpress Pro 10/100B Ethernet");
+ if ((pci_get_vendor(dev) == FXP_VENDORID_INTEL) &&
+ (pci_get_device(dev) == FXP_DEVICEID_i82557)) {
+ device_set_desc(dev, "Intel EtherExpress Pro 10/100B Ethernet");
+ return 0;
+ }
- return NULL;
+ return ENXIO;
}
-static void
-fxp_attach(config_id, unit)
- pcici_t config_id;
- int unit;
+static int
+fxp_attach(device_t dev)
{
- struct fxp_softc *sc;
- vm_offset_t pbase;
+ int error = 0;
+ struct fxp_softc *sc = device_get_softc(dev);
struct ifnet *ifp;
int s;
u_long val;
+ int rid;
- sc = malloc(sizeof(struct fxp_softc), M_DEVBUF, M_NOWAIT);
- if (sc == NULL)
- return;
- bzero(sc, sizeof(struct fxp_softc));
callout_handle_init(&sc->stat_ch);
s = splimp();
@@ -543,39 +527,56 @@ fxp_attach(config_id, unit)
/*
* Enable bus mastering.
*/
- val = pci_conf_read(config_id, PCI_COMMAND_STATUS_REG);
+ val = pci_read_config(dev, PCIR_COMMAND, 2);
val |= (PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
- pci_conf_write(config_id, PCI_COMMAND_STATUS_REG, val);
+ pci_write_config(dev, PCIR_COMMAND, val, 2);
/*
* Map control/status registers.
*/
- if (!pci_map_mem(config_id, FXP_PCI_MMBA,
- (vm_offset_t *)&sc->csr, &pbase)) {
- printf("fxp%d: couldn't map memory\n", unit);
+ rid = FXP_PCI_MMBA;
+ sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!sc->mem) {
+ device_printf(dev, "could not map memory\n");
+ error = ENXIO;
goto fail;
- }
+ }
+ sc->csr = rman_get_virtual(sc->mem); /* XXX use bus_space */
/*
* Allocate our interrupt.
*/
- if (!pci_map_int(config_id, fxp_intr, sc, &net_imask)) {
- printf("fxp%d: couldn't map interrupt\n", unit);
+ rid = 0;
+ sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (sc->irq == NULL) {
+ device_printf(dev, "could not map interrupt\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ error = bus_setup_intr(dev, sc->irq, fxp_intr, sc, &sc->ih);
+ if (error) {
+ device_printf(dev, "could not setup irq\n");
goto fail;
}
/* Do generic parts of attach. */
if (fxp_attach_common(sc, sc->arpcom.ac_enaddr)) {
/* Failed! */
- (void) pci_unmap_int(config_id);
+ bus_teardown_intr(dev, sc->irq, sc->ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, SYS_RES_MEMORY, FXP_PCI_MMBA, sc->mem);
+ error = ENXIO;
goto fail;
}
- printf("fxp%d: Ethernet address %6D%s\n", unit,
+ device_printf(dev, "Ethernet address %6D%s\n",
sc->arpcom.ac_enaddr, ":", sc->phy_10Mbps_only ? ", 10Mbps" : "");
ifp = &sc->arpcom.ac_if;
- ifp->if_unit = unit;
+ ifp->if_unit = device_get_unit(dev);
ifp->if_name = "fxp";
ifp->if_output = ether_output;
ifp->if_baudrate = 100000000;
@@ -600,19 +601,63 @@ fxp_attach(config_id, unit)
bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
#endif
+ splx(s);
+ return 0;
+
+ fail:
+ splx(s);
+ return error;
+}
+
+/*
+ * Detach interface.
+ */
+static int
+fxp_detach(device_t dev)
+{
+ struct fxp_softc *sc = device_get_softc(dev);
+ int s;
+
+ s = splimp();
+
/*
- * Add shutdown hook so that DMA is disabled prior to reboot. Not
- * doing do could allow DMA to corrupt kernel memory during the
- * reboot before the driver initializes.
+ * Close down routes etc.
*/
- at_shutdown(fxp_shutdown, sc, SHUTDOWN_POST_SYNC);
+ if_detach(&sc->arpcom.ac_if);
- splx(s);
- return;
+ /*
+ * Stop DMA and drop transmit queue.
+ */
+ fxp_stop(sc);
+
+ /*
+ * Deallocate resources.
+ */
+ bus_teardown_intr(dev, sc->irq, sc->ih);
+ bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
+ bus_release_resource(dev, SYS_RES_MEMORY, FXP_PCI_MMBA, sc->mem);
+
+ /*
+ * Free all the receive buffers.
+ */
+ if (sc->rfa_headm != NULL)
+ m_freem(sc->rfa_headm);
+
+ /*
+ * Free all media structures.
+ */
+ ifmedia_removeall(&sc->sc_media);
+
+ /*
+ * Free anciliary structures.
+ */
+ free(sc->cbl_base, M_DEVBUF);
+ free(sc->fxp_stats, M_DEVBUF);
+ free(sc->mcsp, M_DEVBUF);
- fail:
- free(sc, M_DEVBUF);
splx(s);
+
+ return 0;
}
/*
@@ -620,14 +665,39 @@ fxp_attach(config_id, unit)
* main purpose of this routine is to shut off receiver DMA so that
* kernel memory doesn't get clobbered during warmboot.
*/
-static void
-fxp_shutdown(howto, sc)
- int howto;
- void *sc;
+static int
+fxp_shutdown(device_t dev)
{
- fxp_stop((struct fxp_softc *) sc);
+ /*
+ * Make sure that DMA is disabled prior to reboot. Not doing
+ * do could allow DMA to corrupt kernel memory during the
+ * reboot before the driver initializes.
+ */
+ fxp_stop((struct fxp_softc *) device_get_softc(dev));
+ return 0;
}
+static device_method_t fxp_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, fxp_probe),
+ DEVMETHOD(device_attach, fxp_attach),
+ DEVMETHOD(device_detach, fxp_detach),
+ DEVMETHOD(device_shutdown, fxp_shutdown),
+
+ { 0, 0 }
+};
+
+static driver_t fxp_driver = {
+ "fxp",
+ fxp_methods,
+ DRIVER_TYPE_NET,
+ sizeof(struct fxp_softc),
+};
+
+static devclass_t fxp_devclass;
+
+DRIVER_MODULE(fxp, pci, fxp_driver, fxp_devclass, 0, 0);
+
#endif /* __NetBSD__ */
/*************************************************************
diff --git a/sys/pci/if_fxpvar.h b/sys/pci/if_fxpvar.h
index ce8d8fe..042d2df 100644
--- a/sys/pci/if_fxpvar.h
+++ b/sys/pci/if_fxpvar.h
@@ -27,7 +27,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: if_fxpvar.h,v 1.5 1998/06/07 17:12:38 dfr Exp $
+ * $Id: if_fxpvar.h,v 1.6 1998/08/02 00:29:15 dg Exp $
*/
/*
@@ -48,6 +48,9 @@ struct fxp_softc {
#else
struct arpcom arpcom; /* per-interface network data */
caddr_t csr; /* control/status registers */
+ struct resource *mem; /* resource descriptor for registers */
+ struct resource *irq; /* resource descriptor for interrupt */
+ void *ih; /* interrupt handler cookie */
#endif /* __NetBSD__ */
struct mbuf *rfa_headm; /* first mbuf in receive frame area */
struct mbuf *rfa_tailm; /* last mbuf in receive frame area */
diff --git a/sys/pci/if_pn.c b/sys/pci/if_pn.c
index 425195e..3209051 100644
--- a/sys/pci/if_pn.c
+++ b/sys/pci/if_pn.c
@@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: if_pn.c,v 1.50 1999/04/14 18:52:02 wpaul Exp $
+ * $Id: if_pn.c,v 1.16 1999/04/14 19:40:07 wpaul Exp $
*/
/*
@@ -97,7 +97,13 @@
#ifndef lint
static const char rcsid[] =
- "$Id: if_pn.c,v 1.50 1999/04/14 18:52:02 wpaul Exp $";
+ "$Id: if_pn.c,v 1.16 1999/04/14 19:40:07 wpaul Exp $";
+#endif
+
+#ifdef __alpha__
+#undef vtophys
+#define vtophys(va) (pmap_kextract(((vm_offset_t) (va))) \
+ + 1*1024*1024*1024)
#endif
/*
diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c
index d9b9e61..e848418 100644
--- a/sys/pci/if_xl.c
+++ b/sys/pci/if_xl.c
@@ -29,7 +29,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: if_xl.c,v 1.30 1999/04/15 03:18:33 wpaul Exp $
+ * $Id: if_xl.c,v 1.31 1999/04/16 01:56:06 ghelmer Exp $
*/
/*
@@ -122,6 +122,12 @@
#include <pci/pcireg.h>
#include <pci/pcivar.h>
+#ifdef __alpha__
+#undef vtophys
+#define vtophys(va) (pmap_kextract(((vm_offset_t) (va))) \
+ + 1*1024*1024*1024)
+#endif
+
/*
* The following #define causes the code to use PIO to access the
* chip's registers instead of memory mapped mode. The reason PIO mode
@@ -158,7 +164,7 @@
#if !defined(lint)
static const char rcsid[] =
- "$Id: if_xl.c,v 1.30 1999/04/15 03:18:33 wpaul Exp $";
+ "$Id: if_xl.c,v 1.31 1999/04/16 01:56:06 ghelmer Exp $";
#endif
/*
@@ -1513,7 +1519,7 @@ xl_attach(config_id, unit)
}
sc->xl_ldata = (struct xl_list_data *)sc->xl_ldata_ptr;
- round = (unsigned int)sc->xl_ldata_ptr & 0xF;
+ round = (uintptr_t)sc->xl_ldata_ptr & 0xF;
roundptr = sc->xl_ldata_ptr;
for (i = 0; i < 8; i++) {
if (round % 8) {
diff --git a/sys/pci/ohci_pci.c b/sys/pci/ohci_pci.c
index 3c20ff7..1aea5f1 100644
--- a/sys/pci/ohci_pci.c
+++ b/sys/pci/ohci_pci.c
@@ -44,6 +44,8 @@
* USB spec: http://www.teleport.com/cgi-bin/mailmerge.cgi/~usb/cgiform.tpl
*/
+#include "opt_bus.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -52,23 +54,13 @@
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/queue.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
-#define PCI_CLASS_SERIALBUS 0x0c000000
-#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x00010000
-#define PCI_SUBCLASS_SERIALBUS_SSA 0x00020000
-#define PCI_SUBCLASS_SERIALBUS_USB 0x00030000
-#define PCI_SUBCLASS_SERIALBUS_FIBER 0x00040000
-
-#define PCI_INTERFACE(d) (((d) >> 8) & 0xff)
-#define PCI_SUBCLASS(d) ((d) & PCI_SUBCLASS_MASK)
-#define PCI_CLASS(d) ((d) & PCI_CLASS_MASK)
-
-
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
@@ -77,7 +69,6 @@
#include <dev/usb/ohcireg.h>
#include <dev/usb/ohcivar.h>
-
#define PCI_OHCI_VENDORID_ALI 0x10b9
#define PCI_OHCI_VENDORID_CMDTECH 0x1095
#define PCI_OHCI_VENDORID_COMPAQ 0x0e11
@@ -98,27 +89,12 @@ static const char *ohci_device_usb0673 = "CMD Tech 673 (USB0673) USB Host Contr
static const char *ohci_device_generic = "OHCI (generic) USB Host Controller";
-
-static const char *ohci_pci_probe __P((pcici_t, pcidi_t));
-static void ohci_pci_attach __P((pcici_t, int));
-
-static u_long ohci_count = 0;
-
-static struct pci_device ohci_pci_device = {
- "ohci",
- ohci_pci_probe,
- ohci_pci_attach,
- &ohci_count,
- NULL
-};
-
-DATA_SET(pcidevice_set, ohci_pci_device);
-
+#define PCI_OHCI_BASE_REG 0x10
static const char *
-ohci_pci_probe(pcici_t config_id, pcidi_t device_id)
+ohci_pci_match(device_t dev)
{
- u_int32_t class;
+ u_int32_t device_id = pci_get_devid(dev);
switch(device_id) {
case PCI_OHCI_DEVICEID_ALADDIN_V:
@@ -132,54 +108,72 @@ ohci_pci_probe(pcici_t config_id, pcidi_t device_id)
case PCI_OHCI_DEVICEID_NEC:
return (ohci_device_nec);
default:
- class = pci_conf_read(config_id, PCI_CLASS_REG);
- if ( (PCI_CLASS(class) == PCI_CLASS_SERIALBUS)
- && (PCI_SUBCLASS(class) == PCI_SUBCLASS_SERIALBUS_USB)
- && (PCI_INTERFACE(class) == PCI_INTERFACE_OHCI)) {
- return(ohci_device_generic);
+ if ( pci_get_class(dev) == PCIC_SERIALBUS
+ && pci_get_subclass(dev) == PCIS_SERIALBUS_USB
+ && pci_get_progif(dev) == PCI_INTERFACE_OHCI) {
+ return (ohci_device_generic);
}
}
return NULL; /* dunno */
}
-static void
-ohci_pci_attach(pcici_t config_id, int unit)
+static int
+ohci_pci_probe(device_t dev)
{
- vm_offset_t pbase;
+ const char *desc = ohci_pci_match(dev);
+ if (desc) {
+ device_set_desc(dev, desc);
+ return 0;
+ } else {
+ return ENXIO;
+ }
+}
+
+static int
+ohci_pci_attach(device_t dev)
+{
+ int unit = device_get_unit(dev);
+ ohci_softc_t *sc = device_get_softc(dev);
device_t usbus;
- ohci_softc_t *sc;
usbd_status err;
- int id;
+ int rid;
+ struct resource *res;
+ void *ih;
+ int error;
+
+ rid = PCI_CBMEM;
+ res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!res) {
+ device_printf(dev, "could not map memory\n");
+ return ENXIO;
+ }
- sc = malloc(sizeof(ohci_softc_t), M_DEVBUF, M_NOWAIT);
- /* Do not free it below, intr might use the sc */
- if ( sc == NULL ) {
- printf("ohci%d: could not allocate memory", unit);
- return;
- }
- memset(sc, 0, sizeof(ohci_softc_t));
+ sc->iot = rman_get_bustag(res);
+ sc->ioh = rman_get_bushandle(res);
- if(!pci_map_mem(config_id, PCI_CBMEM,
- (vm_offset_t *)&sc->sc_iobase, &pbase)) {
- printf("ohci%d: could not map memory\n", unit);
- return;
- }
+ rid = 0;
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (res == NULL) {
+ device_printf(dev, "could not allocate irq\n");
+ return ENOMEM;
+ }
- if ( !pci_map_int(config_id, (pci_inthand_t *)ohci_intr,
- (void *) sc, &bio_imask)) {
- printf("ohci%d: could not map irq\n", unit);
- return;
+ error = bus_setup_intr(dev, res, (driver_intr_t *) ohci_intr, sc, &ih);
+ if (error) {
+ device_printf(dev, "could not setup irq\n");
+ return error;
}
- usbus = device_add_child(root_bus, "usb", -1, sc);
+ usbus = device_add_child(dev, "usb", -1, sc);
if (!usbus) {
- printf("ohci%d: could not add USB device to root bus\n", unit);
- return;
+ printf("ohci%d: could not add USB device\n", unit);
+ return ENOMEM;
}
- id = pci_conf_read(config_id, PCI_ID_REG);
- switch(id) {
+ switch (pci_get_devid(dev)) {
case PCI_OHCI_DEVICEID_ALADDIN_V:
device_set_desc(usbus, ohci_device_aladdin_v);
sprintf(sc->sc_vendor, "AcerLabs");
@@ -202,7 +196,7 @@ ohci_pci_attach(pcici_t config_id, int unit)
break;
default:
if (bootverbose)
- printf("(New OHCI DeviceId=0x%08x)\n", id);
+ printf("(New OHCI DeviceId=0x%08x)\n", pci_get_devid(dev));
device_set_desc(usbus, ohci_device_generic);
sprintf(sc->sc_vendor, "(unknown)");
}
@@ -211,8 +205,36 @@ ohci_pci_attach(pcici_t config_id, int unit)
err = ohci_init(sc);
if (err != USBD_NORMAL_COMPLETION) {
printf("ohci%d: init failed, error=%d\n", unit, err);
- device_delete_child(root_bus, usbus);
+ device_delete_child(dev, usbus);
}
- return;
+ return device_probe_and_attach(sc->sc_bus.bdev);
}
+
+static device_method_t ohci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ohci_pci_probe),
+ DEVMETHOD(device_attach, ohci_pci_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t ohci_driver = {
+ "ohci",
+ ohci_methods,
+ DRIVER_TYPE_BIO,
+ sizeof(ohci_softc_t),
+};
+
+static devclass_t ohci_devclass;
+
+DRIVER_MODULE(ohci, pci, ohci_driver, ohci_devclass, 0, 0);
diff --git a/sys/pci/pci.c b/sys/pci/pci.c
index e449fc2..889550c 100644
--- a/sys/pci/pci.c
+++ b/sys/pci/pci.c
@@ -23,10 +23,12 @@
* (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: pci.c,v 1.93 1999/01/19 23:29:18 se Exp $
+ * $Id: pci.c,v 1.94 1999/04/11 02:47:31 eivind Exp $
*
*/
+#include "opt_bus.h"
+
#include "pci.h"
#if NPCI > 0
@@ -50,6 +52,11 @@
#include <vm/pmap.h>
#include <vm/vm_extern.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#include <pci/pci_ioctl.h>
@@ -338,11 +345,10 @@ pci_readcfg(pcicfgregs *probe)
M_DEVBUF, M_WAITOK);
if (devlist_entry == NULL)
return (NULL);
+ bzero(devlist_entry, sizeof *devlist_entry);
cfg = &devlist_entry->cfg;
- bzero(cfg, sizeof *cfg);
-
cfg->bus = probe->bus;
cfg->slot = probe->slot;
cfg->func = probe->func;
@@ -450,113 +456,6 @@ pci_freecfg(struct pci_devinfo *dinfo)
}
#endif
-static void
-pci_addcfg(struct pci_devinfo *dinfo)
-{
- if (bootverbose) {
- int i;
- pcicfgregs *cfg = &dinfo->cfg;
-
- printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
- cfg->vendor, cfg->device, cfg->revid);
- printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
- cfg->baseclass, cfg->subclass, cfg->progif,
- cfg->hdrtype, cfg->mfdev);
- printf("\tsubordinatebus=%x \tsecondarybus=%x\n",
- cfg->subordinatebus, cfg->secondarybus);
-#ifdef PCI_DEBUG
- printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
- cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
- printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
- cfg->lattimer, cfg->lattimer * 30,
- cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
-#endif /* PCI_DEBUG */
- if (cfg->intpin > 0)
- printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
-
- for (i = 0; i < cfg->nummaps; i++) {
- pcimap *m = &cfg->map[i];
- printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n",
- i, m->type, m->ln2range, m->base, m->ln2size);
- }
- }
- pci_drvattach(dinfo); /* XXX currently defined in pci_compat.c */
-}
-
-/* scan one PCI bus for devices */
-
-static int
-pci_probebus(int bus)
-{
- pcicfgregs probe;
- int bushigh = bus;
-
-#ifdef SIMOS
-#undef PCI_SLOTMAX
-#define PCI_SLOTMAX 0
-#endif
-
- bzero(&probe, sizeof probe);
- /* XXX KDM */
- /* probe.parent = pci_bridgeto(bus); */
- probe.bus = bus;
- for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) {
- int pcifunchigh = 0;
- for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) {
- struct pci_devinfo *dinfo = pci_readcfg(&probe);
- if (dinfo != NULL) {
- if (dinfo->cfg.mfdev)
- pcifunchigh = 7;
- /*
- * XXX: Temporarily move pci_addcfg() up before
- * the use of cfg->subordinatebus. This is
- * necessary, since pci_addcfg() calls the
- * device's probe(), which may read the bus#
- * from some device dependent register of
- * some host to PCI bridges. The probe will
- * eventually be moved to pci_readcfg(), and
- * pci_addcfg() will then be moved back down
- * below the conditional statement ...
- */
- pci_addcfg(dinfo);
-
- if (bushigh < dinfo->cfg.subordinatebus)
- bushigh = dinfo->cfg.subordinatebus;
- if (bushigh < dinfo->cfg.secondarybus)
- bushigh = dinfo->cfg.secondarybus;
-
- /* XXX KDM */
- /* cfg = NULL; we don't own this anymore ... */
- }
- }
- }
- return (bushigh);
-}
-
-/* scan a PCI bus tree reached through one PCI attachment point */
-
-int
-pci_probe(pciattach *parent)
-{
- int bushigh;
- int bus = 0;
-
- STAILQ_INIT(&pci_devq);
-
- bushigh = pci_bushigh();
- while (bus <= bushigh) {
- int newbushigh;
-
- printf("Probing for devices on PCI bus %d:\n", bus);
- newbushigh = pci_probebus(bus);
-
- if (bushigh < newbushigh)
- bushigh = newbushigh;
- bus++;
- }
- return (bushigh);
-}
-
/*
* This is the user interface to PCI configuration space.
*/
@@ -750,8 +649,8 @@ pci_ioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
"pci_match_conf) (%d)\npci_ioctl: "
"pat_buf_len should be = %d\n",
cio->pat_buf_len, cio->num_patterns,
- sizeof(struct pci_match_conf),
- sizeof(struct pci_match_conf) *
+ (int)sizeof(struct pci_match_conf),
+ (int)sizeof(struct pci_match_conf) *
cio->num_patterns);
printf("pci_ioctl: do your headers match your "
"kernel?\n");
@@ -945,4 +844,534 @@ pci_cdevinit(void *dummy)
SYSINIT(pcidev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+PCI_CDEV, pci_cdevinit, NULL);
+#include "pci_if.h"
+
+/*
+ * A simple driver to wrap the old pci driver mechanism for back-compat.
+ */
+
+static int
+pci_compat_probe(device_t dev)
+{
+ struct pci_device *dvp;
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+ const char *name;
+ int error;
+
+ dinfo = device_get_ivars(dev);
+ cfg = &dinfo->cfg;
+ dvp = device_get_driver(dev)->priv;
+
+ /*
+ * Do the wrapped probe.
+ */
+ error = ENXIO;
+ if (dvp && dvp->pd_probe) {
+ name = dvp->pd_probe(cfg, (cfg->device << 16) + cfg->vendor);
+ if (name) {
+ device_set_desc_copy(dev, name);
+ error = 0;
+ }
+ }
+
+ return error;
+}
+
+static int
+pci_compat_attach(device_t dev)
+{
+ struct pci_device *dvp;
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+ int unit;
+
+ dinfo = device_get_ivars(dev);
+ cfg = &dinfo->cfg;
+ dvp = device_get_driver(dev)->priv;
+
+ unit = device_get_unit(dev);
+ if (unit > *dvp->pd_count)
+ *dvp->pd_count = unit;
+ if (dvp->pd_attach)
+ dvp->pd_attach(cfg, unit);
+
+ /*
+ * XXX KDM for some devices, dvp->pd_name winds up NULL.
+ * I haven't investigated enough to figure out why this
+ * would happen.
+ */
+ if (dvp->pd_name != NULL)
+ strncpy(dinfo->conf.pd_name, dvp->pd_name,
+ sizeof(dinfo->conf.pd_name));
+ else
+ strncpy(dinfo->conf.pd_name, "????",
+ sizeof(dinfo->conf.pd_name));
+ dinfo->conf.pd_name[sizeof(dinfo->conf.pd_name) - 1] = 0;
+ dinfo->conf.pd_unit = unit;
+
+ return 0;
+}
+
+static device_method_t pci_compat_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pci_compat_probe),
+ DEVMETHOD(device_attach, pci_compat_attach),
+
+ { 0, 0 }
+};
+
+static devclass_t pci_devclass;
+
+/*
+ * Create a new style driver around each old pci driver.
+ */
+static void
+pci_wrap_old_drivers(void)
+{
+ struct pci_device **dvpp, *dvp;
+
+ dvpp = (struct pci_device **)pcidevice_set.ls_items;
+ while ((dvp = *dvpp++) != NULL) {
+ driver_t *driver;
+ driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT);
+ if (!driver)
+ continue;
+ bzero(driver, sizeof(driver_t));
+ driver->name = dvp->pd_name;
+ driver->methods = pci_compat_methods;
+ driver->type = 0; /* XXX fixup in pci_map_int() */
+ driver->softc = sizeof(struct pci_devinfo *);
+ driver->priv = dvp;
+ devclass_add_driver(pci_devclass, driver);
+ }
+}
+
+/*
+ * New style pci driver. Parent device is either a pci-host-bridge or a
+ * pci-pci-bridge. Both kinds are represented by instances of pcib.
+ */
+
+static void
+pci_print_verbose(struct pci_devinfo *dinfo)
+{
+ if (bootverbose) {
+ int i;
+ pcicfgregs *cfg = &dinfo->cfg;
+
+ printf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n",
+ cfg->vendor, cfg->device, cfg->revid);
+ printf("\tclass=%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n",
+ cfg->baseclass, cfg->subclass, cfg->progif,
+ cfg->hdrtype, cfg->mfdev);
+ printf("\tsubordinatebus=%x \tsecondarybus=%x\n",
+ cfg->subordinatebus, cfg->secondarybus);
+#ifdef PCI_DEBUG
+ printf("\tcmdreg=0x%04x, statreg=0x%04x, cachelnsz=%d (dwords)\n",
+ cfg->cmdreg, cfg->statreg, cfg->cachelnsz);
+ printf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), maxlat=0x%02x (%d ns)\n",
+ cfg->lattimer, cfg->lattimer * 30,
+ cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, cfg->maxlat * 250);
+#endif /* PCI_DEBUG */
+ if (cfg->intpin > 0)
+ printf("\tintpin=%c, irq=%d\n", cfg->intpin +'a' -1, cfg->intline);
+
+ for (i = 0; i < cfg->nummaps; i++) {
+ pcimap *m = &cfg->map[i];
+ printf("\tmap[%d]: type %x, range %2d, base %08x, size %2d\n",
+ i, m->type, m->ln2range, m->base, m->ln2size);
+ }
+ }
+}
+
+static int
+pci_add_children(device_t dev, int busno)
+{
+ pcicfgregs probe;
+ int bushigh = busno;
+
+#ifdef SIMOS
+#undef PCI_SLOTMAX
+#define PCI_SLOTMAX 0
+#endif
+
+ bzero(&probe, sizeof probe);
+ /* XXX KDM */
+ /* probe.parent = pci_bridgeto(bus); */
+ probe.bus = busno;
+ for (probe.slot = 0; probe.slot <= PCI_SLOTMAX; probe.slot++) {
+ int pcifunchigh = 0;
+ for (probe.func = 0; probe.func <= pcifunchigh; probe.func++) {
+ struct pci_devinfo *dinfo = pci_readcfg(&probe);
+ if (dinfo != NULL) {
+ if (dinfo->cfg.mfdev)
+ pcifunchigh = 7;
+
+ pci_print_verbose(dinfo);
+ dinfo->cfg.dev =
+ device_add_child(dev, NULL, -1, dinfo);
+
+ if (bushigh < dinfo->cfg.subordinatebus)
+ bushigh = dinfo->cfg.subordinatebus;
+ if (bushigh < dinfo->cfg.secondarybus)
+ bushigh = dinfo->cfg.secondarybus;
+ }
+ }
+ }
+
+ return bushigh;
+}
+
+static int
+pci_new_probe(device_t dev)
+{
+ STAILQ_INIT(&pci_devq);
+ device_set_desc(dev, "PCI bus");
+
+ pci_add_children(dev, device_get_unit(dev));
+
+ return 0;
+}
+
+static void
+pci_print_child(device_t dev, device_t child)
+{
+ printf(" at device %d.%d", pci_get_slot(child), pci_get_function(child));
+ printf(" on %s%d", device_get_name(dev), device_get_unit(dev));
+}
+
+static int
+pci_read_ivar(device_t dev, device_t child, int which, u_long *result)
+{
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+
+ dinfo = device_get_ivars(child);
+ cfg = &dinfo->cfg;
+
+ switch (which) {
+ case PCI_IVAR_SUBVENDOR:
+ *result = cfg->subvendor;
+ break;
+ case PCI_IVAR_SUBDEVICE:
+ *result = cfg->subdevice;
+ break;
+ case PCI_IVAR_VENDOR:
+ *result = cfg->vendor;
+ break;
+ case PCI_IVAR_DEVICE:
+ *result = cfg->device;
+ break;
+ case PCI_IVAR_DEVID:
+ *result = (cfg->device << 16) | cfg->vendor;
+ break;
+ case PCI_IVAR_CLASS:
+ *result = cfg->baseclass;
+ break;
+ case PCI_IVAR_SUBCLASS:
+ *result = cfg->subclass;
+ break;
+ case PCI_IVAR_PROGIF:
+ *result = cfg->progif;
+ break;
+ case PCI_IVAR_REVID:
+ *result = cfg->revid;
+ break;
+ case PCI_IVAR_INTPIN:
+ *result = cfg->intpin;
+ break;
+ case PCI_IVAR_IRQ:
+ *result = cfg->intline;
+ break;
+ case PCI_IVAR_BUS:
+ *result = cfg->bus;
+ break;
+ case PCI_IVAR_SLOT:
+ *result = cfg->slot;
+ break;
+ case PCI_IVAR_FUNCTION:
+ *result = cfg->func;
+ break;
+ case PCI_IVAR_SECONDARYBUS:
+ *result = cfg->secondarybus;
+ break;
+ case PCI_IVAR_SUBORDINATEBUS:
+ *result = cfg->subordinatebus;
+ break;
+ default:
+ return ENOENT;
+ }
+ return 0;
+}
+
+static int
+pci_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
+{
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+
+ dinfo = device_get_ivars(child);
+ cfg = &dinfo->cfg;
+
+ switch (which) {
+ case PCI_IVAR_SUBVENDOR:
+ case PCI_IVAR_SUBDEVICE:
+ case PCI_IVAR_VENDOR:
+ case PCI_IVAR_DEVICE:
+ case PCI_IVAR_DEVID:
+ case PCI_IVAR_CLASS:
+ case PCI_IVAR_SUBCLASS:
+ case PCI_IVAR_PROGIF:
+ case PCI_IVAR_REVID:
+ case PCI_IVAR_INTPIN:
+ case PCI_IVAR_IRQ:
+ case PCI_IVAR_BUS:
+ case PCI_IVAR_SLOT:
+ case PCI_IVAR_FUNCTION:
+ return EINVAL; /* disallow for now */
+
+ case PCI_IVAR_SECONDARYBUS:
+ cfg->secondarybus = value;
+ break;
+ case PCI_IVAR_SUBORDINATEBUS:
+ cfg->subordinatebus = value;
+ break;
+ default:
+ return ENOENT;
+ }
+ return 0;
+}
+
+static int
+pci_mapno(pcicfgregs *cfg, int reg)
+{
+ int i, nummaps;
+ pcimap *map;
+
+ nummaps = cfg->nummaps;
+ map = cfg->map;
+
+ for (i = 0; i < nummaps; i++)
+ if (map[i].reg == reg)
+ return (i);
+ return (-1);
+}
+
+static int
+pci_porten(pcicfgregs *cfg)
+{
+ return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0);
+}
+
+static int
+pci_isportmap(pcicfgregs *cfg, int map)
+
+{
+ return ((unsigned)map < cfg->nummaps
+ && (cfg->map[map].type & PCI_MAPPORT) != 0);
+}
+
+static int
+pci_memen(pcicfgregs *cfg)
+{
+ return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0);
+}
+
+static int
+pci_ismemmap(pcicfgregs *cfg, int map)
+{
+ return ((unsigned)map < cfg->nummaps
+ && (cfg->map[map].type & PCI_MAPMEM) != 0);
+}
+
+static struct resource *
+pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ int isdefault;
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ struct resource *rv, **rvp = 0;
+ int map;
+
+ isdefault = (device_get_parent(child) == dev
+ && start == 0UL && end == ~0UL && count == 1);
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (*rid != 0)
+ return 0;
+ if (isdefault && cfg->intline != 255) {
+ start = cfg->intline;
+ end = cfg->intline;
+ count = 1;
+ }
+ break;
+
+ case SYS_RES_DRQ: /* passthru for child isa */
+ break;
+
+ case SYS_RES_MEMORY:
+ if (isdefault) {
+ map = pci_mapno(cfg, *rid);
+ if (pci_memen(cfg) && pci_ismemmap(cfg, map)) {
+ start = cfg->map[map].base;
+ count = 1 << cfg->map[map].ln2size;
+ end = start + count;
+ rvp = &cfg->map[map].res;
+ } else
+ return 0;
+ }
+ break;
+
+ case SYS_RES_IOPORT:
+ if (isdefault) {
+ map = pci_mapno(cfg, *rid);
+ if (pci_porten(cfg) && pci_isportmap(cfg, map)) {
+ start = cfg->map[map].base;
+ count = 1 << cfg->map[map].ln2size;
+ end = start + count;
+ rvp = &cfg->map[map].res;
+ } else
+ return 0;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+
+ rv = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ type, rid, start, end, count, flags);
+ if (rvp)
+ *rvp = rv;
+
+ return rv;
+}
+
+static int
+pci_release_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
+{
+ int rv;
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ int map = 0;
+
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (rid != 0)
+ return EINVAL;
+ break;
+
+ case SYS_RES_DRQ: /* passthru for child isa */
+ break;
+
+ case SYS_RES_MEMORY:
+ case SYS_RES_IOPORT:
+ /*
+ * Only check the map registers if this is a direct
+ * descendant.
+ */
+ if (device_get_parent(child) == dev)
+ map = pci_mapno(cfg, rid);
+ else
+ map = -1;
+ break;
+
+ default:
+ return (ENOENT);
+ }
+
+ rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r);
+
+ if (rv == 0) {
+ switch (type) {
+ case SYS_RES_IRQ:
+ cfg->irqres = 0;
+ break;
+
+ case SYS_RES_DRQ: /* passthru for child isa */
+ break;
+
+ case SYS_RES_MEMORY:
+ case SYS_RES_IOPORT:
+ if (map != -1)
+ cfg->map[map].res = 0;
+ break;
+
+ default:
+ return ENOENT;
+ }
+ }
+
+ return rv;
+}
+
+static u_int32_t
+pci_read_config_method(device_t dev, device_t child, int reg, int width)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ return pci_cfgread(cfg, reg, width);
+}
+
+static void
+pci_write_config_method(device_t dev, device_t child, int reg,
+ u_int32_t val, int width)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ pci_cfgwrite(cfg, reg, val, width);
+}
+
+static int
+pci_modevent(module_t mod, int what, void *arg)
+{
+ switch (what) {
+ case MOD_LOAD:
+ pci_wrap_old_drivers();
+ break;
+
+ case MOD_UNLOAD:
+ break;
+ }
+
+ return 0;
+}
+
+static device_method_t pci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pci_new_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, pci_print_child),
+ DEVMETHOD(bus_read_ivar, pci_read_ivar),
+ DEVMETHOD(bus_write_ivar, pci_write_ivar),
+ DEVMETHOD(bus_driver_added, bus_generic_driver_added),
+ DEVMETHOD(bus_alloc_resource, pci_alloc_resource),
+ DEVMETHOD(bus_release_resource, pci_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ /* PCI interface */
+ DEVMETHOD(pci_read_config, pci_read_config_method),
+ DEVMETHOD(pci_write_config, pci_write_config_method),
+
+ { 0, 0 }
+};
+
+static driver_t pci_driver = {
+ "pci",
+ pci_methods,
+ DRIVER_TYPE_MISC,
+ 1, /* no softc */
+};
+
+DRIVER_MODULE(pci, pcib, pci_driver, pci_devclass, pci_modevent, 0);
+
#endif /* NPCI > 0 */
diff --git a/sys/pci/pci_compat.c b/sys/pci/pci_compat.c
index f107e54..bfa1d59 100644
--- a/sys/pci/pci_compat.c
+++ b/sys/pci/pci_compat.c
@@ -23,10 +23,12 @@
* (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: pci_compat.c,v 1.20 1999/01/19 23:29:19 se Exp $
+ * $Id: pci_compat.c,v 1.21 1999/04/11 02:46:20 eivind Exp $
*
*/
+#include "opt_bus.h"
+
#include "pci.h"
#if NPCI > 0
@@ -41,6 +43,11 @@
#include <vm/pmap.h>
#include <sys/interrupt.h>
+#include <sys/bus.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
+
#include <pci/pcireg.h>
#include <pci/pcivar.h>
@@ -56,118 +63,45 @@
/* ------------------------------------------------------------------------- */
-static int
-pci_mapno(pcicfgregs *cfg, int reg)
-{
- int i, nummaps;
- pcimap *map;
-
- nummaps = cfg->nummaps;
- map = cfg->map;
-
- for (i = 0; i < nummaps; i++)
- if (map[i].reg == reg)
- return (i);
- return (-1);
-}
-
-static int
-pci_porten(pcicfgregs *cfg)
-{
- return ((cfg->cmdreg & PCIM_CMD_PORTEN) != 0);
-}
-
-static int
-pci_isportmap(pcicfgregs *cfg, int map)
-
-{
- return ((unsigned)map < cfg->nummaps
- && (cfg->map[map].type & PCI_MAPPORT) != 0);
-}
-
-static int
-pci_memen(pcicfgregs *cfg)
-{
- return ((cfg->cmdreg & PCIM_CMD_MEMEN) != 0);
-}
-
-static int
-pci_ismemmap(pcicfgregs *cfg, int map)
-{
- return ((unsigned)map < cfg->nummaps
- && (cfg->map[map].type & PCI_MAPMEM) != 0);
-}
-
-/* ------------------------------------------------------------------------- */
-
u_long
-pci_conf_read(pcici_t tag, u_long reg)
+pci_conf_read(pcici_t cfg, u_long reg)
{
- return (pci_cfgread(tag, reg, 4));
+ return (pci_read_config(cfg->dev, reg, 4));
}
void
-pci_conf_write(pcici_t tag, u_long reg, u_long data)
+pci_conf_write(pcici_t cfg, u_long reg, u_long data)
{
- pci_cfgwrite(tag, reg, data, 4);
+ pci_write_config(cfg->dev, reg, data, 4);
}
int pci_map_port(pcici_t cfg, u_long reg, pci_port_t* pa)
{
- int map;
-
- map = pci_mapno(cfg, reg);
- if (pci_porten(cfg) && pci_isportmap(cfg, map)) {
- u_int32_t iobase;
- u_int32_t iosize;
-
- iobase = cfg->map[map].base;
- iosize = 1 << cfg->map[map].ln2size;
-#ifdef RESOURCE_CHECK
- if (resource_claim(cfg, REST_PORT, RESF_NONE,
- iobase, iobase + iosize -1) == 0)
-#endif /* RESOURCE_CHECK */
- {
- *pa = iobase;
- return (1);
- }
+ int rid;
+ struct resource *res;
+
+ rid = reg;
+ res = bus_alloc_resource(cfg->dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (res) {
+ *pa = rman_get_start(res);
+ return (1);
}
return (0);
}
int pci_map_mem(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
{
- int map;
-
- map = pci_mapno(cfg, reg);
- if (pci_memen(cfg) && pci_ismemmap(cfg, map)) {
- u_int32_t paddr;
- u_int32_t psize;
-
- paddr = cfg->map[map].base;
- psize = 1 << cfg->map[map].ln2size;
-#ifdef RESOURCE_CHECK
- if (resource_claim(cfg, REST_MEM, RESF_NONE,
- paddr, paddr + psize -1) == 0)
-#endif /* RESOURCE_CHECK */
- {
- u_int32_t poffs;
- vm_offset_t vaddr;
-
- poffs = paddr - trunc_page(paddr);
-#ifdef __i386__
- vaddr = (vm_offset_t)pmap_mapdev(paddr-poffs, psize+poffs);
-#endif
-#ifdef __alpha__
- vaddr = paddr-poffs;
-#endif
- if (vaddr != NULL) {
- vaddr += poffs;
- *va = vaddr;
- *pa = paddr;
- return (1);
- }
- }
+ int rid;
+ struct resource *res;
+
+ rid = reg;
+ res = bus_alloc_resource(cfg->dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (res) {
+ *pa = rman_get_start(res);
+ *va = (vm_offset_t) rman_get_virtual(res);
+ return (1);
}
return (0);
}
@@ -175,7 +109,7 @@ int pci_map_mem(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
int
pci_map_dense(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
{
- if(pci_map_mem(cfg, reg, va, pa)){
+ if (pci_map_mem(cfg, reg, va, pa)){
#ifdef __alpha__
vm_offset_t dense;
@@ -195,7 +129,7 @@ pci_map_dense(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
int
pci_map_bwx(pcici_t cfg, u_long reg, vm_offset_t* va, vm_offset_t* pa)
{
- if(pci_map_mem(cfg, reg, va, pa)){
+ if (pci_map_mem(cfg, reg, va, pa)){
#ifdef __alpha__
vm_offset_t bwx;
@@ -228,14 +162,42 @@ pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg,
#endif
if (cfg->intpin != 0) {
int irq = cfg->intline;
- void *dev_instance = (void *)-1; /* XXX use cfg->devdata */
- void *idesc;
+ driver_t *driver = device_get_driver(cfg->dev);
+ int rid = 0;
+ struct resource *res;
+ void *ih;
+ res = bus_alloc_resource(cfg->dev, SYS_RES_IRQ, &rid,
+ irq, irq, 1, RF_SHAREABLE|RF_ACTIVE);
+ if (!res) {
+ printf("pci_map_int: can't allocate interrupt\n");
+ return 0;
+ }
- idesc = intr_create(dev_instance, irq, handler, arg, maskptr,
- flags);
- error = intr_connect(idesc);
+ /*
+ * This is ugly. Translate the mask into a driver type.
+ */
+ if (maskptr == &tty_imask)
+ driver->type |= DRIVER_TYPE_TTY;
+ else if (maskptr == &bio_imask)
+ driver->type |= DRIVER_TYPE_BIO;
+ else if (maskptr == &net_imask)
+ driver->type |= DRIVER_TYPE_NET;
+ else if (maskptr == &cam_imask)
+ driver->type |= DRIVER_TYPE_CAM;
+
+ error = BUS_SETUP_INTR(device_get_parent(cfg->dev), cfg->dev,
+ res, handler, arg, &ih);
if (error != 0)
return 0;
+
+#ifdef NEW_BUS_PCI
+ /*
+ * XXX this apic stuff looks totally busted. It should
+ * move to the nexus code which actually registers the
+ * interrupt.
+ */
+#endif
+
#ifdef APIC_IO
nextpin = next_apic_irq(irq);
@@ -265,11 +227,21 @@ pci_map_int_right(pcici_t cfg, pci_inthand_t *handler, void *arg,
nextpin = next_apic_irq(irq);
while (nextpin >= 0) {
- idesc = intr_create(dev_instance, nextpin, handler,
- arg, maskptr, flags);
- error = intr_connect(idesc);
- if (error != 0)
+ rid = 0;
+ res = bus_alloc_resource(cfg->dev, SYS_RES_IRQ, &rid,
+ nextpin, nextpin, 1,
+ RF_SHAREABLE|RF_ACTIVE);
+ if (!res) {
+ printf("pci_map_int: can't allocate extra interrupt\n");
+ return 0;
+ }
+ error = BUS_SETUP_INTR(device_get_parent(cfg->dev),
+ cfg->dev, res, handler, arg,
+ &ih);
+ if (error != 0) {
+ printf("pci_map_int: BUS_SETUP_INTR failed\n");
return 0;
+ }
printf("Registered extra interrupt handler for int %d (in addition to int %d)\n", nextpin, irq);
nextpin = next_apic_irq(nextpin);
}
@@ -284,6 +256,7 @@ pci_unmap_int(pcici_t cfg)
return (0); /* not supported, yet, since cfg doesn't know about idesc */
}
+#if 0
/* ------------------------------------------------------------------------- */
/*
@@ -464,6 +437,7 @@ int pci_register_lkm (struct pci_device *dvp, int if_revision)
if (lkm == NULL) {
return (-1);
}
+ bzero(lkm, sizeof (*lkm));
lkm->dvp = dvp;
lkm->next = pci_lkm_head;
@@ -480,5 +454,7 @@ pci_configure(void)
/* ------------------------------------------------------------------------- */
+#endif
+
#endif /* PCI_COMPAT */
#endif /* NPCI > 0 */
diff --git a/sys/pci/pci_if.m b/sys/pci/pci_if.m
new file mode 100644
index 0000000..b2fa675
--- /dev/null
+++ b/sys/pci/pci_if.m
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 1998 Doug Rabson
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $Id$
+#
+
+INTERFACE pci;
+
+METHOD u_int32_t read_config {
+ device_t dev;
+ device_t child;
+ int reg;
+ int width;
+};
+
+METHOD void write_config {
+ device_t dev;
+ device_t child;
+ int reg;
+ u_int32_t val;
+ int width;
+};
diff --git a/sys/pci/pcireg.h b/sys/pci/pcireg.h
index 0adb540..9c0dba0 100644
--- a/sys/pci/pcireg.h
+++ b/sys/pci/pcireg.h
@@ -26,7 +26,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: pcireg.h,v 1.19 1997/09/20 07:41:58 dyson Exp $
+ * $Id: pcireg.h,v 1.20 1998/10/07 03:40:51 gibbs Exp $
*
*/
@@ -173,7 +173,7 @@
#define PCIS_MEMORY_OTHER 0x80
#define PCIC_BRIDGE 0x06
-#define PCIS_BRDIGE_HOST 0x00
+#define PCIS_BRIDGE_HOST 0x00
#define PCIS_BRIDGE_ISA 0x01
#define PCIS_BRIDGE_EISA 0x02
#define PCIS_BRIDGE_MCA 0x03
diff --git a/sys/pci/pcisupport.c b/sys/pci/pcisupport.c
index b292c92..1fe5f1e 100644
--- a/sys/pci/pcisupport.c
+++ b/sys/pci/pcisupport.c
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** $Id: pcisupport.c,v 1.94 1999/02/21 11:39:37 dfr Exp $
+** $Id: pcisupport.c,v 1.95 1999/04/07 03:59:13 msmith Exp $
**
** Device driver for DEC/INTEL PCI chipsets.
**
@@ -41,6 +41,7 @@
***************************************************************************
*/
+#include "opt_bus.h"
#include "opt_pci.h"
#include "opt_smp.h"
#include "intpm.h"
@@ -50,6 +51,7 @@
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
+#include <sys/bus.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
@@ -65,19 +67,7 @@
**---------------------------------------------------------
*/
-static const char* chipset_probe (pcici_t tag, pcidi_t type);
-static void chipset_attach(pcici_t tag, int unit);
-static u_long chipset_count;
-
-static struct pci_device chipset_device = {
- "chip",
- chipset_probe,
- chipset_attach,
- &chipset_count,
- NULL
-};
-
-DATA_SET (pcidevice_set, chipset_device);
+static void chipset_attach(device_t dev, int unit);
struct condmsg {
unsigned char port;
@@ -127,20 +117,22 @@ generic_pci_bridge (pcici_t tag)
*/
static void
-fixbushigh_orion(pcici_t tag)
+fixbushigh_orion(device_t dev)
{
- tag->secondarybus = pci_cfgread(tag, 0x4a, 1);
- tag->subordinatebus = pci_cfgread(tag, 0x4b, 1);
+ pci_set_secondarybus(dev, pci_read_config(dev, 0x4a, 1));
+ pci_set_subordinatebus(dev, pci_read_config(dev, 0x4b, 1));
}
static void
-fixbushigh_i1225(pcici_t tag)
+fixbushigh_i1225(device_t dev)
{
int sublementarybus;
- sublementarybus = pci_cfgread(tag, 0x41, 1);
- if (sublementarybus != 0xff)
- tag->secondarybus = tag->subordinatebus = sublementarybus +1;
+ sublementarybus = pci_read_config(dev, 0x41, 1);
+ if (sublementarybus != 0xff) {
+ pci_set_secondarybus(dev, sublementarybus + 1);
+ pci_set_subordinatebus(dev, sublementarybus + 1);
+ }
}
@@ -158,7 +150,7 @@ fixbushigh_i1225(pcici_t tag)
* most sense.
*/
static void
-fixbushigh_450nx(pcici_t tag)
+fixbushigh_450nx(device_t dev)
{
int subordinatebus;
unsigned long devmap;
@@ -170,7 +162,7 @@ fixbushigh_450nx(pcici_t tag)
* If this doesn't find all the PCI busses, complain to the
* BIOS vendor. There is nothing more we can do.
*/
- devmap = pci_cfgread(tag, 0xd6, 2) & 0x3c;
+ devmap = pci_read_config(dev, 0xd6, 2) & 0x3c;
if (!devmap)
panic("450NX MIOC: No host to PCI bridges marked present.\n");
/*
@@ -178,13 +170,13 @@ fixbushigh_450nx(pcici_t tag)
* find the highest bus, and use those numbers.
*/
if (devmap & 0x20) { /* B1 */
- subordinatebus = pci_cfgread(tag, 0xd5, 1);
+ subordinatebus = pci_read_config(dev, 0xd5, 1);
} else if (devmap & 0x10) { /* A1 */
- subordinatebus = pci_cfgread(tag, 0xd4, 1);
+ subordinatebus = pci_read_config(dev, 0xd4, 1);
} else if (devmap & 0x8) { /* B0 */
- subordinatebus = pci_cfgread(tag, 0xd2, 1);
+ subordinatebus = pci_read_config(dev, 0xd2, 1);
} else /* if (devmap & 0x4) */ { /* A0 */
- subordinatebus = pci_cfgread(tag, 0xd1, 1);
+ subordinatebus = pci_read_config(dev, 0xd1, 1);
}
if (subordinatebus == 255) {
printf("fixbushigh_450nx: bogus highest PCI bus %d",
@@ -201,214 +193,44 @@ fixbushigh_450nx(pcici_t tag)
printf("fixbushigh_450nx: subordinatebus is %d\n",
subordinatebus);
- tag->secondarybus = tag->subordinatebus = subordinatebus;
+ pci_set_secondarybus(dev, subordinatebus);
+ pci_set_subordinatebus(dev, subordinatebus);
}
static void
-fixbushigh_Ross(pcici_t tag)
+fixbushigh_Ross(device_t dev)
{
int secondarybus;
/* just guessing the secondary bus register number ... */
- secondarybus = pci_cfgread(tag, 0x45, 1);
- if (secondarybus != 0)
- tag->secondarybus = tag->subordinatebus = secondarybus + 1;
+ secondarybus = pci_read_config(dev, 0x45, 1);
+ if (secondarybus != 0) {
+ pci_set_secondarybus(dev, secondarybus + 1);
+ pci_set_subordinatebus(dev, secondarybus + 1);
+ }
}
static void
-fixwsc_natoma(pcici_t tag)
+fixwsc_natoma(device_t dev)
{
int pmccfg;
- pmccfg = pci_cfgread(tag, 0x50, 2);
+ pmccfg = pci_read_config(dev, 0x50, 2);
#if defined(SMP)
if (pmccfg & 0x8000) {
printf("Correcting Natoma config for SMP\n");
pmccfg &= ~0x8000;
- pci_cfgwrite(tag, 0x50, 2, pmccfg);
+ pci_write_config(dev, 0x50, 2, pmccfg);
}
#else
if ((pmccfg & 0x8000) == 0) {
printf("Correcting Natoma config for non-SMP\n");
pmccfg |= 0x8000;
- pci_cfgwrite(tag, 0x50, 2, pmccfg);
+ pci_write_config(dev, 0x50, 2, pmccfg);
}
#endif
}
-
-static const char*
-chipset_probe (pcici_t tag, pcidi_t type)
-{
- unsigned rev;
- char *descr;
-
- switch (type) {
- case 0x00088086:
- /* Silently ignore this one! What is it, anyway ??? */
- return ("");
- case 0x04868086:
- return ("Intel 82425EX PCI system controller");
- case 0x04848086:
- rev = (unsigned) pci_conf_read (tag, PCI_CLASS_REG) & 0xff;
- if (rev == 3)
- return ("Intel 82378ZB PCI to ISA bridge");
- return ("Intel 82378IB PCI to ISA bridge");
- case 0x04838086:
- return ("Intel 82424ZX (Saturn) cache DRAM controller");
- case 0x04828086:
- return ("Intel 82375EB PCI-EISA bridge");
- case 0x04a38086:
- rev = (unsigned) pci_conf_read (tag, PCI_CLASS_REG) & 0xff;
- if (rev == 16 || rev == 17)
- return ("Intel 82434NX (Neptune) PCI cache memory controller");
- return ("Intel 82434LX (Mercury) PCI cache memory controller");
- case 0x12258086:
- fixbushigh_i1225(tag);
- return ("Intel 824?? host to PCI bridge");
- case 0x122d8086:
- return ("Intel 82437FX PCI cache memory controller");
- case 0x122e8086:
- return ("Intel 82371FB PCI to ISA bridge");
- case 0x12348086:
- return ("Intel 82371MX mobile PCI I/O IDE accelerator (MPIIX)");
- case 0x12358086:
- return ("Intel 82437MX mobile PCI cache memory controller");
- case 0x12508086:
- return ("Intel 82439");
- case 0x70008086:
- return ("Intel 82371SB PCI to ISA bridge");
- case 0x70308086:
- return ("Intel 82437VX PCI cache memory controller");
- case 0x71008086:
- return ("Intel 82439TX System Controller (MTXC)");
- case 0x71108086:
- return ("Intel 82371AB PCI to ISA bridge");
- case 0x71138086:
-#if NINTPM > 0
- return NULL; /* Need to stop generic_pci_bridge() */
-#else
- return ("Intel 82371AB Power management controller");
-#endif
- case 0x71908086:
- return ("Intel 82443BX host to PCI bridge");
- case 0x71918086:
- return ("Intel 82443BX host to AGP bridge");
- case 0x71928086:
- return ("Intel 82443BX host to PCI bridge (AGP disabled)");
- case 0x12378086:
- fixwsc_natoma(tag);
- return ("Intel 82440FX (Natoma) PCI and memory controller");
- case 0x84c48086:
- fixbushigh_orion(tag);
- return ("Intel 82454KX/GX (Orion) host to PCI bridge");
- case 0x84c58086:
- return ("Intel 82453KX/GX (Orion) PCI memory controller");
- case 0x84ca8086:
- fixbushigh_450nx(tag);
- return ("Intel 82451NX Memory and I/O Controller");
- case 0x84cb8086:
- return ("Intel 82454NX PCI Expander Bridge");
- case 0x00221014:
- return ("IBM 82351 PCI-PCI bridge");
- case 0x00011011:
- return ("DEC 21050 PCI-PCI bridge");
- case 0x124b8086:
- return ("Intel 82380FB mobile PCI to PCI bridge");
- /* SiS -- vendor 0x1039 */
- case 0x04961039:
- return ("SiS 85c496");
- case 0x04061039:
- return ("SiS 85c501");
- case 0x00081039:
- return ("SiS 85c503");
- case 0x06011039:
- return ("SiS 85c601");
-
- /* VLSI -- vendor 0x1004 */
- case 0x00051004:
- return ("VLSI 82C592 Host to PCI bridge");
- case 0x00061004:
- return ("VLSI 82C593 PCI to ISA bridge");
- case 0x01011004:
- return ("VLSI 82C532 Eagle II Peripheral Controller");
- case 0x01021004:
- return ("VLSI 82C534 Eagle II PCI Bus bridge");
- case 0x01031004:
- return ("VLSI 82C538 Eagle II PCI Docking bridge");
- case 0x01041004:
- return ("VLSI 82C535 Eagle II System Controller");
- case 0x01051004:
- return ("VLSI 82C147 IrDA Controller");
-
- /* VIA Technologies -- vendor 0x1106
- * Note that the old Apollo Master chipset is not in here, as VIA
- * does not seem to have any docs on their website for it, and I do
- * not have a Master board in my posession. -LC */
-
- case 0x05851106:
- return("VIA 82C585 (Apollo VP1/VPX) system controller");
- case 0x05861106: /* south bridge section -- IDE is covered in ide_pci.c */
- return("VIA 82C586 PCI-ISA bridge");
- case 0x05951106:
- case 0x15951106:
- return("VIA 82C595 (Apollo VP2) system controller");
- case 0x05971106:
- return("VIA 82C597 (Apollo VP3) system controller");
- /* XXX need info on the MVP3 -- any takers? */
- case 0x30401106:
- return("VIA 82C586B ACPI interface");
- /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */
- /* totally. Please let me know if anything wrong. -F */
- case 0x05981106:
- return("VIA 82C598MVP (Apollo MVP3) host bridge");
- case 0x85981106:
- return("VIA 82C598MVP (Apollo MVP3) PCI-PCI bridge");
-
- /* AcerLabs -- vendor 0x10b9 */
- /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */
- /* id is '10b9" but the register always shows "10b9". -Foxfair */
- case 0x154110b9:
- return("AcerLabs M1541 (Aladdin-V) PCI host bridge");
- case 0x153310b9:
- return("AcerLabs M1533 portable PCI-ISA bridge");
- case 0x154310b9:
- return("AcerLabs M1543 desktop PCI-ISA bridge");
- case 0x524710b9:
- return("AcerLabs M5247 PCI-PCI(AGP Supported) bridge");
- case 0x524310b9:/* 5243 seems like 5247, need more info to divide*/
- return("AcerLabs M5243 PCI-PCI bridge");
- case 0x710110b9:
-#if NALPM > 0
- return NULL; /* Need to stop generic_pci_bridge() */
-#else
- return("AcerLabs M15x3 Power Management Unit");
-#endif
-
- /* NEC -- vendor 0x1033 */
- case 0x00011033:
- return ("NEC 0001 PCI to PC-98 C-bus bridge");
- case 0x00021033:
- return ("NEC 0002 PCI to PC-98 local bus bridge");
- case 0x00161033:
- return ("NEC 0016 PCI to PC-98 local bus bridge");
- case 0x002c1033:
- return ("NEC 002C PCI to PC-98 C-bus bridge");
- case 0x003b1033:
- return ("NEC 003B PCI to PC-98 C-bus bridge");
-
- /* Ross (?) -- vendor 0x1166 */
- case 0x00051166:
- fixbushigh_Ross(tag);
- return ("Ross (?) host to PCI bridge");
- };
-
- if ((descr = generic_pci_bridge(tag)) != NULL)
- return descr;
-
- return NULL;
-}
-
#ifndef PCI_QUIET
#define M_XX 0 /* end of list */
@@ -848,17 +670,8 @@ static const struct condmsg conf82371fb2[] =
{ 0 }
};
-static char confread (pcici_t config_id, int port)
-{
- unsigned long portw = port & ~3;
- unsigned long ports = (port - portw) << 3;
-
- unsigned long l = pci_conf_read (config_id, portw);
- return (l >> ports);
-}
-
static void
-writeconfig (pcici_t config_id, const struct condmsg *tbl)
+writeconfig (device_t dev, const struct condmsg *tbl)
{
while (tbl->flags != M_XX) {
const char *text = 0;
@@ -866,7 +679,7 @@ writeconfig (pcici_t config_id, const struct condmsg *tbl)
if (tbl->flags == M_TR) {
text = tbl->text;
} else {
- unsigned char v = (unsigned char) confread(config_id, tbl->port);
+ unsigned char v = pci_read_config(dev, tbl->port, 1);
switch (tbl->flags) {
case M_EQ:
if ((v & tbl->mask) == tbl->value) text = tbl->text;
@@ -888,14 +701,14 @@ writeconfig (pcici_t config_id, const struct condmsg *tbl)
#ifdef DUMPCONFIGSPACE
static void
-dumpconfigspace (pcici_t tag)
+dumpconfigspace (device_t dev)
{
int reg;
printf ("configuration space registers:");
for (reg = 0; reg < 0x100; reg+=4) {
if ((reg & 0x0f) == 0)
printf ("\n%02x:\t", reg);
- printf ("%08x ", pci_conf_read (tag, reg));
+ printf ("%08x ", pci_read_config(dev, reg, 4));
}
printf ("\n");
}
@@ -904,49 +717,448 @@ dumpconfigspace (pcici_t tag)
#endif /* PCI_QUIET */
static void
-chipset_attach (pcici_t config_id, int unit)
+chipset_attach (device_t dev, int unit)
{
#ifndef PCI_QUIET
if (!bootverbose)
return;
- switch (pci_conf_read (config_id, PCI_ID_REG)) {
+ switch (pci_get_devid(dev)) {
case 0x04868086:
- writeconfig (config_id, conf82425ex);
+ writeconfig (dev, conf82425ex);
break;
case 0x04838086:
- writeconfig (config_id, conf82424zx);
+ writeconfig (dev, conf82424zx);
break;
case 0x04a38086:
- writeconfig (config_id, conf82434lx);
+ writeconfig (dev, conf82434lx);
break;
case 0x04848086:
- writeconfig (config_id, conf82378);
+ writeconfig (dev, conf82378);
break;
case 0x122d8086:
- writeconfig (config_id, conf82437fx);
+ writeconfig (dev, conf82437fx);
break;
case 0x70308086:
- writeconfig (config_id, conf82437vx);
+ writeconfig (dev, conf82437vx);
break;
case 0x70008086:
case 0x122e8086:
- writeconfig (config_id, conf82371fb);
+ writeconfig (dev, conf82371fb);
break;
case 0x70108086:
case 0x12308086:
- writeconfig (config_id, conf82371fb2);
+ writeconfig (dev, conf82371fb2);
break;
#if 0
case 0x00011011: /* DEC 21050 */
case 0x00221014: /* IBM xxx */
- writeconfig (config_id, conf_pci2pci);
+ writeconfig (dev, conf_pci2pci);
break;
#endif
};
#endif /* PCI_QUIET */
}
+static const char *
+pci_bridge_type(device_t dev)
+{
+ char *descr, tmpbuf[120];
+
+ if (pci_get_class(dev) != PCIC_BRIDGE)
+ return NULL;
+
+ switch (pci_get_subclass(dev)) {
+ case PCIS_BRIDGE_HOST: strcpy(tmpbuf, "Host to PCI"); break;
+ case PCIS_BRIDGE_ISA: strcpy(tmpbuf, "PCI to ISA"); break;
+ case PCIS_BRIDGE_EISA: strcpy(tmpbuf, "PCI to EISA"); break;
+ case PCIS_BRIDGE_MCA: strcpy(tmpbuf, "PCI to MCA"); break;
+ case PCIS_BRIDGE_PCI: strcpy(tmpbuf, "PCI to PCI"); break;
+ case PCIS_BRIDGE_PCMCIA: strcpy(tmpbuf, "PCI to PCMCIA"); break;
+ case PCIS_BRIDGE_NUBUS: strcpy(tmpbuf, "PCI to NUBUS"); break;
+ case PCIS_BRIDGE_CARDBUS: strcpy(tmpbuf, "PCI to CardBus"); break;
+ default:
+ snprintf(tmpbuf, sizeof(tmpbuf),
+ "PCI to 0x%x", pci_get_subclass(dev));
+ break;
+ }
+ snprintf(tmpbuf+strlen(tmpbuf), sizeof(tmpbuf)-strlen(tmpbuf),
+ " bridge (vendor=%04x device=%04x)",
+ pci_get_vendor(dev), pci_get_device(dev));
+ descr = malloc (strlen(tmpbuf) +1, M_DEVBUF, M_WAITOK);
+ strcpy(descr, tmpbuf);
+ return descr;
+}
+
+static const char*
+pcib_match(device_t dev)
+{
+ switch (pci_get_devid(dev)) {
+ case 0x84cb8086:
+ return ("Intel 82454NX PCI Expander Bridge");
+ case 0x00221014:
+ return ("IBM 82351 PCI-PCI bridge");
+ case 0x00011011:
+ return ("DEC 21050 PCI-PCI bridge");
+ case 0x124b8086:
+ return ("Intel 82380FB mobile PCI to PCI bridge");
+
+ /* VLSI -- vendor 0x1004 */
+ case 0x01021004:
+ return ("VLSI 82C534 Eagle II PCI Bus bridge");
+ case 0x01031004:
+ return ("VLSI 82C538 Eagle II PCI Docking bridge");
+
+ /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */
+ /* totally. Please let me know if anything wrong. -F */
+ case 0x85981106:
+ return("VIA 82C598MVP (Apollo MVP3) PCI-PCI bridge");
+
+ /* AcerLabs -- vendor 0x10b9 */
+ /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */
+ /* id is '10b9" but the register always shows "10b9". -Foxfair */
+ case 0x524710b9:
+ return("AcerLabs M5247 PCI-PCI(AGP Supported) bridge");
+ case 0x524310b9:/* 5243 seems like 5247, need more info to divide*/
+ return("AcerLabs M5243 PCI-PCI bridge");
+
+ };
+
+ if (pci_get_class(dev) == PCIC_BRIDGE
+ && pci_get_subclass(dev) == PCIS_BRIDGE_PCI)
+ return pci_bridge_type(dev);
+
+ return NULL;
+}
+
+static int pcib_probe(device_t dev)
+{
+ const char *desc;
+
+ desc = pcib_match(dev);
+ if (desc) {
+ device_set_desc_copy(dev, desc);
+ return 0;
+ }
+
+ return ENXIO;
+}
+
+static int pcib_attach(device_t dev)
+{
+ struct pci_devinfo *dinfo;
+ pcicfgregs *cfg;
+
+ dinfo = device_get_ivars(dev);
+ cfg = &dinfo->cfg;
+
+ chipset_attach(dev, device_get_unit(dev));
+
+ if (cfg->secondarybus) {
+ device_add_child(dev, "pci", cfg->secondarybus, 0);
+ return bus_generic_attach(dev);
+ } else
+ return 0;
+}
+
+static device_method_t pcib_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, pcib_probe),
+ DEVMETHOD(device_attach, pcib_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t pcib_driver = {
+ "pcib",
+ pcib_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+static devclass_t pcib_devclass;
+
+DRIVER_MODULE(pcib, pci, pcib_driver, pcib_devclass, 0, 0);
+
+static const char *
+isab_match(device_t dev)
+{
+ unsigned rev;
+
+ switch (pci_get_devid(dev)) {
+ case 0x04848086:
+ rev = pci_get_revid(dev);
+ if (rev == 3)
+ return ("Intel 82378ZB PCI to ISA bridge");
+ return ("Intel 82378IB PCI to ISA bridge");
+ case 0x04828086:
+ return ("Intel 82375EB PCI-EISA bridge");
+ case 0x122e8086:
+ return ("Intel 82371FB PCI to ISA bridge");
+ case 0x70008086:
+ return ("Intel 82371SB PCI to ISA bridge");
+ case 0x71108086:
+ return ("Intel 82371AB PCI to ISA bridge");
+
+ /* VLSI -- vendor 0x1004 */
+ case 0x00061004:
+ return ("VLSI 82C593 PCI to ISA bridge");
+
+ /* VIA Technologies -- vendor 0x1106
+ * Note that the old Apollo Master chipset is not in here, as VIA
+ * does not seem to have any docs on their website for it, and I do
+ * not have a Master board in my posession. -LC */
+
+ case 0x05861106: /* south bridge section -- IDE is covered in ide_pci.c */
+ return("VIA 82C586 PCI-ISA bridge");
+
+ /* AcerLabs -- vendor 0x10b9 */
+ /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */
+ /* id is '10b9" but the register always shows "10b9". -Foxfair */
+ case 0x153310b9:
+ return("AcerLabs M1533 portable PCI-ISA bridge");
+ case 0x154310b9:
+ return("AcerLabs M1543 desktop PCI-ISA bridge");
+ }
+
+ if (pci_get_class(dev) == PCIC_BRIDGE
+ && (pci_get_subclass(dev) == PCIS_BRIDGE_ISA
+ || pci_get_subclass(dev) == PCIS_BRIDGE_EISA))
+ return pci_bridge_type(dev);
+
+ return NULL;
+}
+
+static int
+isab_probe(device_t dev)
+{
+ const char *desc;
+
+ desc = isab_match(dev);
+ if (desc) {
+ device_set_desc_copy(dev, desc);
+ /* Don't bother adding more than one ISA bus */
+ if (!devclass_get_device(devclass_find("isa"), 0))
+ device_add_child(dev, "isa", -1, 0);
+ return 0;
+ }
+
+ return ENXIO;
+}
+
+static device_method_t isab_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, isab_probe),
+ DEVMETHOD(device_attach, bus_generic_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t isab_driver = {
+ "isab",
+ isab_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+static devclass_t isab_devclass;
+
+DRIVER_MODULE(isab, pci, isab_driver, isab_devclass, 0, 0);
+
+static const char*
+chip_match(device_t dev)
+{
+ unsigned rev;
+
+ switch (pci_get_devid(dev)) {
+ case 0x00088086:
+ /* Silently ignore this one! What is it, anyway ??? */
+ return ("");
+ case 0x71108086:
+ /*
+ * On my laptop (Tecra 8000DVD), this device has a
+ * bogus subclass 0x80 so make sure that it doesn't
+ * match the generic 'chip' driver by accident.
+ */
+ return NULL;
+ case 0x12258086:
+ fixbushigh_i1225(dev);
+ return ("Intel 824?? host to PCI bridge");
+ case 0x71908086:
+ return ("Intel 82443BX host to PCI bridge");
+ case 0x71918086:
+ return ("Intel 82443BX host to AGP bridge");
+ case 0x71928086:
+ return ("Intel 82443BX host to PCI bridge (AGP disabled)");
+ case 0x84c48086:
+ fixbushigh_orion(dev);
+ return ("Intel 82454KX/GX (Orion) host to PCI bridge");
+ case 0x84ca8086:
+ fixbushigh_450nx(dev);
+ return ("Intel 82451NX Memory and I/O Controller");
+ case 0x04868086:
+ return ("Intel 82425EX PCI system controller");
+ case 0x04838086:
+ return ("Intel 82424ZX (Saturn) cache DRAM controller");
+ case 0x04a38086:
+ rev = pci_get_revid(dev);
+ if (rev == 16 || rev == 17)
+ return ("Intel 82434NX (Neptune) PCI cache memory controller");
+ return ("Intel 82434LX (Mercury) PCI cache memory controller");
+ case 0x122d8086:
+ return ("Intel 82437FX PCI cache memory controller");
+ case 0x12348086:
+ return ("Intel 82371MX mobile PCI I/O IDE accelerator (MPIIX)");
+ case 0x12358086:
+ return ("Intel 82437MX mobile PCI cache memory controller");
+ case 0x12508086:
+ return ("Intel 82439");
+ case 0x70308086:
+ return ("Intel 82437VX PCI cache memory controller");
+ case 0x71008086:
+ return ("Intel 82439TX System Controller (MTXC)");
+
+ case 0x71138086:
+ return ("Intel 82371AB Power management controller");
+ case 0x12378086:
+ fixwsc_natoma(dev);
+ return ("Intel 82440FX (Natoma) PCI and memory controller");
+ case 0x84c58086:
+ return ("Intel 82453KX/GX (Orion) PCI memory controller");
+ /* SiS -- vendor 0x1039 */
+ case 0x04961039:
+ return ("SiS 85c496");
+ case 0x04061039:
+ return ("SiS 85c501");
+ case 0x00081039:
+ return ("SiS 85c503");
+ case 0x06011039:
+ return ("SiS 85c601");
+
+ /* VLSI -- vendor 0x1004 */
+ case 0x00051004:
+ return ("VLSI 82C592 Host to PCI bridge");
+ case 0x01011004:
+ return ("VLSI 82C532 Eagle II Peripheral Controller");
+ case 0x01041004:
+ return ("VLSI 82C535 Eagle II System Controller");
+ case 0x01051004:
+ return ("VLSI 82C147 IrDA Controller");
+
+ /* VIA Technologies -- vendor 0x1106
+ * Note that the old Apollo Master chipset is not in here, as VIA
+ * does not seem to have any docs on their website for it, and I do
+ * not have a Master board in my posession. -LC */
+
+ case 0x05851106:
+ return("VIA 82C585 (Apollo VP1/VPX) system controller");
+ case 0x05951106:
+ case 0x15951106:
+ return("VIA 82C595 (Apollo VP2) system controller");
+ case 0x05971106:
+ return("VIA 82C597 (Apollo VP3) system controller");
+ /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */
+ /* totally. Please let me know if anything wrong. -F */
+ /* XXX need info on the MVP3 -- any takers? */
+ case 0x05981106:
+ return("VIA 82C598MVP (Apollo MVP3) host bridge");
+ case 0x30401106:
+ return("VIA 82C586B ACPI interface");
+#if 0
+ /* XXX New info added-in */
+ case 0x05711106:
+ return("VIA 82C586B IDE controller");
+ case 0x30381106:
+ return("VIA 82C586B USB controller");
+#endif
+
+ /* NEC -- vendor 0x1033 */
+ case 0x00011033:
+ return ("NEC 0001 PCI to PC-98 C-bus bridge");
+ case 0x00021033:
+ return ("NEC 0002 PCI to PC-98 local bus bridge");
+ case 0x00161033:
+ return ("NEC 0016 PCI to PC-98 local bus bridge");
+ case 0x002c1033:
+ return ("NEC 002C PCI to PC-98 C-bus bridge");
+ case 0x003b1033:
+ return ("NEC 003B PCI to PC-98 C-bus bridge");
+
+ /* AcerLabs -- vendor 0x10b9 */
+ /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */
+ /* id is '10b9" but the register always shows "10b9". -Foxfair */
+ case 0x154110b9:
+ return("AcerLabs M1541 (Aladdin-V) PCI host bridge");
+ };
+
+ if (pci_get_class(dev) == PCIC_BRIDGE
+ && pci_get_subclass(dev) != PCIS_BRIDGE_PCI
+ && pci_get_subclass(dev) != PCIS_BRIDGE_ISA
+ && pci_get_subclass(dev) != PCIS_BRIDGE_EISA)
+ return pci_bridge_type(dev);
+
+ return NULL;
+}
+
+static int chip_probe(device_t dev)
+{
+ const char *desc;
+
+ desc = chip_match(dev);
+ if (desc) {
+ device_set_desc_copy(dev, desc);
+ return 0;
+ }
+
+ return ENXIO;
+}
+
+static int chip_attach(device_t dev)
+{
+ chipset_attach(dev, device_get_unit(dev));
+
+ return 0;
+}
+
+static device_method_t chip_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, chip_probe),
+ DEVMETHOD(device_attach, chip_attach),
+
+ { 0, 0 }
+};
+
+static driver_t chip_driver = {
+ "chip",
+ chip_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+static devclass_t chip_devclass;
+
+DRIVER_MODULE(chip, pci, chip_driver, chip_devclass, 0, 0);
+
/*---------------------------------------------------------
**
** Catchall driver for VGA devices
@@ -957,29 +1169,16 @@ chipset_attach (pcici_t config_id, int unit)
**---------------------------------------------------------
*/
-static const char* vga_probe (pcici_t tag, pcidi_t type);
-static void vga_attach (pcici_t tag, int unit);
-static u_long vga_count;
-
-static struct pci_device vga_device = {
- "vga",
- vga_probe,
- vga_attach,
- &vga_count,
- NULL
-};
-
-DATA_SET (pcidevice_set, vga_device);
-
-static const char* vga_probe (pcici_t tag, pcidi_t typea)
+static const char* vga_match(device_t dev)
{
- int data = pci_conf_read(tag, PCI_CLASS_REG);
- u_int id = pci_conf_read(tag, PCI_ID_REG);
+ /* int data = pci_conf_read(tag, PCI_CLASS_REG); */
+ u_int id = pci_get_devid(dev);
const char *vendor, *chip, *type;
- vendor = chip = type = 0;
+ return 0; /* XXX interferes with syscons */
- switch (id & 0xffff) {
+ vendor = chip = type = 0;
+ switch (id) {
case 0x10c8:
vendor = "NeoMagic";
switch (id >> 16) {
@@ -1209,20 +1408,18 @@ static const char* vga_probe (pcici_t tag, pcidi_t typea)
return buf;
}
- switch (data & PCI_CLASS_MASK) {
+ switch (pci_get_class(dev)) {
- case PCI_CLASS_PREHISTORIC:
- if ((data & PCI_SUBCLASS_MASK)
- != PCI_SUBCLASS_PREHISTORIC_VGA)
+ case PCIC_OLD:
+ if (pci_get_subclass(dev) != PCIS_OLD_VGA)
return 0;
if (type == 0)
type = "VGA-compatible display device";
break;
- case PCI_CLASS_DISPLAY:
+ case PCIC_DISPLAY:
if (type == 0) {
- if ((data & PCI_SUBCLASS_MASK)
- == PCI_SUBCLASS_DISPLAY_VGA)
+ if (pci_get_subclass(dev) != PCIS_DISPLAY_VGA)
type = "VGA-compatible display device";
else {
/*
@@ -1260,7 +1457,20 @@ static const char* vga_probe (pcici_t tag, pcidi_t typea)
return type;
}
-static void vga_attach (pcici_t tag, int unit)
+static int vga_probe(device_t dev)
+{
+ const char *desc;
+
+ desc = vga_match(dev);
+ if (desc) {
+ device_set_desc(dev, desc);
+ return 0;
+ }
+
+ return ENXIO;
+}
+
+static int vga_attach(device_t dev)
{
/*
** If the assigned addresses are remapped,
@@ -1273,42 +1483,27 @@ static void vga_attach (pcici_t tag, int unit)
for (reg = PCI_MAP_REG_START; reg < PCI_MAP_REG_END; reg += 4)
(void) pci_map_mem (tag, reg, &va, &pa);
#endif
+ return 0;
}
-/*---------------------------------------------------------
-**
-** Hook for loadable pci drivers
-**
-**---------------------------------------------------------
-*/
-
-static const char* lkm_probe (pcici_t tag, pcidi_t type);
-static void lkm_attach (pcici_t tag, int unit);
-static u_long lkm_count;
+static device_method_t vga_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, vga_probe),
+ DEVMETHOD(device_attach, vga_attach),
-static struct pci_device lkm_device = {
- "lkm",
- lkm_probe,
- lkm_attach,
- &lkm_count,
- NULL
+ { 0, 0 }
};
-DATA_SET (pcidevice_set, lkm_device);
+static driver_t vga_driver = {
+ "vga",
+ vga_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
-static const char*
-lkm_probe (pcici_t tag, pcidi_t type)
-{
- /*
- ** Not yet!
- ** (Should try to load a matching driver)
- */
- return ((char*)0);
-}
+static devclass_t vga_devclass;
-static void
-lkm_attach (pcici_t tag, int unit)
-{}
+DRIVER_MODULE(vga, pci, vga_driver, vga_devclass, 0, 0);
/*---------------------------------------------------------
**
@@ -1317,32 +1512,39 @@ lkm_attach (pcici_t tag, int unit)
**---------------------------------------------------------
*/
-static const char* ign_probe (pcici_t tag, pcidi_t type);
-static void ign_attach (pcici_t tag, int unit);
-static u_long ign_count;
-
-static struct pci_device ign_device = {
- NULL,
- ign_probe,
- ign_attach,
- &ign_count,
- NULL
-};
-
-DATA_SET (pcidevice_set, ign_device);
-
-static const char*
-ign_probe (pcici_t tag, pcidi_t type)
+static int
+ign_probe (device_t dev)
{
- switch (type) {
+ switch (pci_get_devid(dev)) {
case 0x10001042ul: /* wd */
- return ("");
+ return 0;
/* return ("SMC FDC 37c665");*/
};
- return ((char*)0);
+ return ENXIO;
}
-static void
-ign_attach (pcici_t tag, int unit)
-{}
+static int
+ign_attach (device_t dev)
+{
+ return 0;
+}
+
+static device_method_t ign_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ign_probe),
+ DEVMETHOD(device_attach, ign_attach),
+
+ { 0, 0 }
+};
+
+static driver_t ign_driver = {
+ "ign",
+ ign_methods,
+ DRIVER_TYPE_MISC,
+ 1,
+};
+
+static devclass_t ign_devclass;
+
+DRIVER_MODULE(ign, pci, ign_driver, ign_devclass, 0, 0);
diff --git a/sys/pci/pcivar.h b/sys/pci/pcivar.h
index 7843e3a..55f72a1 100644
--- a/sys/pci/pcivar.h
+++ b/sys/pci/pcivar.h
@@ -23,7 +23,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: pcivar.h,v 1.24 1999/01/13 04:59:19 bde Exp $
+ * $Id: pcivar.h,v 1.25 1999/01/19 23:29:20 se Exp $
*
*/
@@ -67,13 +67,17 @@ typedef struct {
u_int8_t ln2size;
u_int8_t ln2range;
u_int8_t reg; /* offset of map register in config space */
+/* u_int8_t dummy;*/
+ struct resource *res; /* handle from resource manager */
} pcimap;
/* config header information common to all header types */
typedef struct pcicfg {
+ struct device *dev; /* device which owns this */
pcimap *map; /* pointer to array of PCI maps */
void *hdrspec; /* pointer to header type specific data */
+ struct resource *irqres; /* resource descriptor for interrupt mapping */
u_int16_t subvendor; /* card vendor ID */
u_int16_t subdevice; /* card device ID, assigned by card vendor */
@@ -182,6 +186,79 @@ void pci_cfgwrite (pcicfgregs *cfg, int reg, int data, int bytes);
vm_offset_t pci_cvt_to_dense (vm_offset_t);
vm_offset_t pci_cvt_to_bwx (vm_offset_t);
#endif /* __alpha__ */
+
+#ifdef _SYS_BUS_H_
+
+#include "pci_if.h"
+
+enum pci_device_ivars {
+ PCI_IVAR_SUBVENDOR,
+ PCI_IVAR_SUBDEVICE,
+ PCI_IVAR_VENDOR,
+ PCI_IVAR_DEVICE,
+ PCI_IVAR_DEVID,
+ PCI_IVAR_CLASS,
+ PCI_IVAR_SUBCLASS,
+ PCI_IVAR_PROGIF,
+ PCI_IVAR_REVID,
+ PCI_IVAR_INTPIN,
+ PCI_IVAR_IRQ,
+ PCI_IVAR_BUS,
+ PCI_IVAR_SLOT,
+ PCI_IVAR_FUNCTION,
+ PCI_IVAR_SECONDARYBUS,
+ PCI_IVAR_SUBORDINATEBUS,
+};
+
+/*
+ * Simplified accessors for pci devices
+ */
+#define PCI_ACCESSOR(A, B, T) \
+ \
+static __inline T pci_get_ ## A(device_t dev) \
+{ \
+ uintptr_t v; \
+ BUS_READ_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, &v); \
+ return (T) v; \
+} \
+ \
+static __inline void pci_set_ ## A(device_t dev, T t) \
+{ \
+ u_long v = (u_long) t; \
+ BUS_WRITE_IVAR(device_get_parent(dev), dev, PCI_IVAR_ ## B, v); \
+}
+
+PCI_ACCESSOR(subvendor, SUBVENDOR, u_int16_t)
+PCI_ACCESSOR(subdevice, SUBDEVICE, u_int16_t)
+PCI_ACCESSOR(vendor, VENDOR, u_int16_t)
+PCI_ACCESSOR(device, DEVICE, u_int16_t)
+PCI_ACCESSOR(devid, DEVID, u_int32_t)
+PCI_ACCESSOR(class, CLASS, u_int8_t)
+PCI_ACCESSOR(subclass, SUBCLASS, u_int8_t)
+PCI_ACCESSOR(progif, PROGIF, u_int8_t)
+PCI_ACCESSOR(revid, REVID, u_int8_t)
+PCI_ACCESSOR(intpin, INTPIN, u_int8_t)
+PCI_ACCESSOR(irq, IRQ, u_int8_t)
+PCI_ACCESSOR(bus, BUS, u_int8_t)
+PCI_ACCESSOR(slot, SLOT, u_int8_t)
+PCI_ACCESSOR(function, FUNCTION, u_int8_t)
+PCI_ACCESSOR(secondarybus, SECONDARYBUS, u_int8_t)
+PCI_ACCESSOR(subordinatebus, SUBORDINATEBUS, u_int8_t)
+
+static __inline u_int32_t
+pci_read_config(device_t dev, int reg, int width)
+{
+ return PCI_READ_CONFIG(device_get_parent(dev), dev, reg, width);
+}
+
+static __inline void
+pci_write_config(device_t dev, int reg, u_int32_t val, int width)
+{
+ PCI_WRITE_CONFIG(device_get_parent(dev), dev, reg, val, width);
+}
+
+#endif
+
/* for compatibility to FreeBSD-2.2 version of PCI code */
#ifdef PCI_COMPAT
diff --git a/sys/pci/uhci_pci.c b/sys/pci/uhci_pci.c
index 6ed3cee..4bddf8b 100644
--- a/sys/pci/uhci_pci.c
+++ b/sys/pci/uhci_pci.c
@@ -1,4 +1,4 @@
-/* FreeBSD $Id: uhci_pci.c,v 1.4 1999/04/06 23:09:58 n_hibma Exp $ */
+/* FreeBSD $Id: uhci_pci.c,v 1.5 1999/04/11 14:24:20 n_hibma Exp $ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -37,6 +37,8 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#include "opt_bus.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -45,23 +47,13 @@
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/queue.h>
+#include <machine/bus.h>
+#include <sys/rman.h>
+#include <machine/resource.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
-#define PCI_CLASS_SERIALBUS 0x0c000000
-#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_FIREWIRE 0x00000000
-#define PCI_SUBCLASS_SERIALBUS_ACCESS 0x00010000
-#define PCI_SUBCLASS_SERIALBUS_SSA 0x00020000
-#define PCI_SUBCLASS_SERIALBUS_USB 0x00030000
-#define PCI_SUBCLASS_SERIALBUS_FIBER 0x00040000
-
-#define PCI_INTERFACE(d) (((d)>>8)&0xff)
-#define PCI_SUBCLASS(d) ((d)&PCI_SUBCLASS_MASK)
-#define PCI_CLASS(d) ((d)&PCI_CLASS_MASK)
-
-
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
@@ -70,7 +62,6 @@
#include <dev/usb/uhcireg.h>
#include <dev/usb/uhcivar.h>
-
#define PCI_UHCI_VENDORID_INTEL 0x8086
#define PCI_UHCI_VENDORID_VIA 0x1106
@@ -85,26 +76,10 @@ static const char *uhci_device_generic = "UHCI (generic) USB Controller";
#define PCI_UHCI_BASE_REG 0x20
-static const char *uhci_pci_probe __P((pcici_t, pcidi_t));
-static void uhci_pci_attach __P((pcici_t, int));
-
-static u_long uhci_count = 0;
-
-static struct pci_device uhci_pci_device = {
- "uhci",
- uhci_pci_probe,
- uhci_pci_attach,
- &uhci_count,
- NULL
-};
-
-DATA_SET(pcidevice_set, uhci_pci_device);
-
-
static const char *
-uhci_pci_probe(pcici_t config_id, pcidi_t device_id)
+uhci_pci_match(device_t dev)
{
- u_int32_t class;
+ u_int32_t device_id = pci_get_devid(dev);
if (device_id == PCI_UHCI_DEVICEID_PIIX3) {
return (uhci_device_piix3);
@@ -113,10 +88,9 @@ uhci_pci_probe(pcici_t config_id, pcidi_t device_id)
} else if (device_id == PCI_UHCI_DEVICEID_VT83C572) {
return (uhci_device_vt83c572);
} else {
- class = pci_conf_read(config_id, PCI_CLASS_REG);
- if ( PCI_CLASS(class) == PCI_CLASS_SERIALBUS
- && PCI_SUBCLASS(class) == PCI_SUBCLASS_SERIALBUS_USB
- && PCI_INTERFACE(class) == PCI_INTERFACE_UHCI) {
+ if ( pci_get_class(dev) == PCIC_SERIALBUS
+ && pci_get_subclass(dev) == PCIS_SERIALBUS_USB
+ && pci_get_progif(dev) == PCI_INTERFACE_UHCI) {
return (uhci_device_generic);
}
}
@@ -124,42 +98,64 @@ uhci_pci_probe(pcici_t config_id, pcidi_t device_id)
return NULL; /* dunno... */
}
-static void
-uhci_pci_attach(pcici_t config_id, int unit)
+static int
+uhci_pci_probe(device_t dev)
+{
+ const char *desc = uhci_pci_match(dev);
+ if (desc) {
+ device_set_desc(dev, desc);
+ return 0;
+ } else {
+ return ENXIO;
+ }
+}
+
+static int
+uhci_pci_attach(device_t dev)
{
- int id, legsup;
+ int unit = device_get_unit(dev);
+ int legsup;
char *typestr;
usbd_status err;
- uhci_softc_t *sc = NULL;
device_t usbus;
-
- sc = malloc(sizeof(uhci_softc_t), M_DEVBUF, M_NOWAIT);
- /* Do not free it below, intr might use the sc */
- if ( sc == NULL ) {
- printf("uhci%d: could not allocate memory", unit);
- return;
+ uhci_softc_t *sc = device_get_softc(dev);
+ int rid;
+ struct resource *res;
+ void *ih;
+ int error;
+
+ rid = PCI_UHCI_BASE_REG;
+ res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!res) {
+ device_printf(dev, "could not map ports\n");
+ return ENXIO;
+ }
+
+ sc->iot = rman_get_bustag(res);
+ sc->ioh = rman_get_bushandle(res);
+
+ rid = 0;
+ res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (res == NULL) {
+ device_printf(dev, "could not allocate irq\n");
+ return ENOMEM;
}
- memset(sc, 0, sizeof(uhci_softc_t));
-
- if ( !pci_map_port(config_id, PCI_UHCI_BASE_REG, &sc->sc_iobase) ) {
- printf("uhci%d: could not map port\n", unit);
- return;
- }
-
- if ( !pci_map_int(config_id, (pci_inthand_t *)uhci_intr,
- (void *) sc, &bio_imask)) {
- printf("uhci%d: could not map irq\n", unit);
- return;
+
+ error = bus_setup_intr(dev, res, (driver_intr_t *) uhci_intr, sc, &ih);
+ if (error) {
+ device_printf(dev, "could not setup irq\n");
+ return error;
}
- usbus = device_add_child(root_bus, "usb", -1, sc);
+ usbus = device_add_child(dev, "usb", -1, sc);
if (!usbus) {
- printf("usb%d: could not add USB device to root bus\n", unit);
- return;
+ printf("usb%d: could not add USB device\n", unit);
+ return ENOMEM;
}
- id = pci_conf_read(config_id, PCI_ID_REG);
- switch (id) {
+ switch (pci_get_devid(dev)) {
case PCI_UHCI_DEVICEID_PIIX3:
device_set_desc(usbus, uhci_device_piix3);
sprintf(sc->sc_vendor, "Intel");
@@ -173,13 +169,13 @@ uhci_pci_attach(pcici_t config_id, int unit)
sprintf(sc->sc_vendor, "VIA");
break;
default:
- printf("(New UHCI DeviceId=0x%08x)\n", id);
+ printf("(New UHCI DeviceId=0x%08x)\n", pci_get_devid(dev));
device_set_desc(usbus, uhci_device_generic);
- sprintf(sc->sc_vendor, "(0x%08x)", id);
+ sprintf(sc->sc_vendor, "(0x%08x)", pci_get_devid(dev));
}
if (bootverbose) {
- switch(pci_conf_read(config_id, PCI_USBREV) & PCI_USBREV_MASK) {
+ switch(pci_read_config(dev, PCI_USBREV, 4) & PCI_USBREV_MASK) {
case PCI_USBREV_PRE_1_0:
typestr = "pre 1.0";
break;
@@ -191,25 +187,53 @@ uhci_pci_attach(pcici_t config_id, int unit)
break;
}
printf("uhci%d: USB version %s, chip rev. %d\n", unit, typestr,
- (int) pci_conf_read(config_id, PCIR_REVID) & 0xff);
+ pci_get_revid(dev));
}
- legsup = pci_conf_read(config_id, PCI_LEGSUP);
+ legsup = pci_read_config(dev, PCI_LEGSUP, 4);
if ( !(legsup & PCI_LEGSUP_USBPIRQDEN) ) {
#if ! (defined(USBVERBOSE) || defined(USB_DEBUG))
if (bootverbose)
#endif
printf("uhci%d: PIRQD enable not set\n", unit);
legsup |= PCI_LEGSUP_USBPIRQDEN;
- pci_conf_write(config_id, PCI_LEGSUP, legsup);
+ pci_write_config(dev, PCI_LEGSUP, legsup, 4);
}
sc->sc_bus.bdev = usbus;
err = uhci_init(sc);
if (err != USBD_NORMAL_COMPLETION) {
printf("uhci%d: init failed, error=%d\n", unit, err);
- device_delete_child(root_bus, usbus);
+ device_delete_child(dev, usbus);
}
- return;
+ return device_probe_and_attach(sc->sc_bus.bdev);
}
+
+static device_method_t uhci_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, uhci_pci_probe),
+ DEVMETHOD(device_attach, uhci_pci_attach),
+
+ /* Bus interface */
+ DEVMETHOD(bus_print_child, bus_generic_print_child),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
+ DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
+
+ { 0, 0 }
+};
+
+static driver_t uhci_driver = {
+ "uhci",
+ uhci_methods,
+ DRIVER_TYPE_BIO,
+ sizeof(uhci_softc_t),
+};
+
+static devclass_t uhci_devclass;
+
+DRIVER_MODULE(uhci, pci, uhci_driver, uhci_devclass, 0, 0);
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 3c7f9de..9095d7e 100644
--- a/sys/sys/bus.h
+++ b/sys/sys/bus.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bus.h,v 1.9 1999/03/06 16:52:04 bde Exp $
+ * $Id: bus.h,v 1.10 1999/03/29 08:54:19 dfr Exp $
*/
#ifndef _SYS_BUS_H_
@@ -75,6 +75,7 @@ struct driver {
size_t softc; /* size of device softc struct */
void *priv; /* driver private data */
device_ops_t ops; /* compiled method table */
+ int refs; /* # devclasses containing driver */
};
typedef enum device_state {
@@ -106,6 +107,7 @@ int bus_generic_attach(device_t dev);
int bus_generic_deactivate_resource(device_t dev, device_t child, int type,
int rid, struct resource *r);
int bus_generic_detach(device_t dev);
+void bus_generic_driver_added(device_t dev, driver_t *driver);
void bus_generic_print_child(device_t dev, device_t child);
int bus_generic_read_ivar(device_t dev, device_t child, int which,
uintptr_t *result);
@@ -195,6 +197,7 @@ int devclass_get_maxunit(devclass_t dc);
/*
* Access functions for device resources.
*/
+
int resource_int_value(const char *name, int unit, char *resname,
int *result);
int resource_long_value(const char *name, int unit, char *resname,
@@ -204,6 +207,11 @@ int resource_string_value(const char *name, int unit, char *resname,
int resource_query_string(int i, char *resname, char *value);
char *resource_query_name(int i);
int resource_query_unit(int i);
+int resource_locate(int i, char *resname);
+int resource_set_int(int i, char *resname, int value);
+int resource_set_long(int i, char *resname, long value);
+int resource_set_string(int i, char *resname, char *value);
+int resource_count(void);
/*
* Shorthand for constructing method tables.
diff --git a/sys/sys/bus_private.h b/sys/sys/bus_private.h
index 8ac9944..9c138c5 100644
--- a/sys/sys/bus_private.h
+++ b/sys/sys/bus_private.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: bus_private.h,v 1.4 1998/11/14 21:58:41 wollman Exp $
+ * $Id: bus_private.h,v 1.5 1999/03/29 08:54:19 dfr Exp $
*/
#ifndef _SYS_BUS_PRIVATE_H_
@@ -138,6 +138,7 @@ struct device {
struct device_op_desc {
unsigned int offset; /* offset in driver ops */
+ struct method* method; /* internal method implementation */
const char* name; /* unique name (for registration) */
};
diff --git a/sys/sys/rman.h b/sys/sys/rman.h
index 224d9ed..278e33c 100644
--- a/sys/sys/rman.h
+++ b/sys/sys/rman.h
@@ -26,7 +26,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: rman.h,v 1.1 1998/10/29 01:48:30 wollman Exp $
*/
#ifndef _SYS_RMAN_H_
@@ -51,6 +51,8 @@ struct resource {
u_long r_end; /* index of the last entry (inclusive) */
u_int r_flags;
void *r_virtual; /* virtual address of this resource */
+ bus_space_tag_t r_bustag; /* bus_space tag */
+ bus_space_handle_t r_bushandle; /* bus_space handle */
struct device *r_dev; /* device which has allocated this resource */
struct rman *r_rm; /* resource manager from whence this came */
};
@@ -88,8 +90,15 @@ struct resource *rman_reserve_resource(struct rman *rm, u_long start,
u_long end, u_long count,
u_int flags, struct device *dev);
+#define rman_get_start(r) ((r)->r_start)
+#define rman_get_end(r) ((r)->r_end)
+#define rman_get_flags(r) ((r)->r_flags)
#define rman_set_virtual(r,v) ((r)->r_virtual = (v))
#define rman_get_virtual(r) ((r)->r_virtual)
+#define rman_set_bustag(r,t) ((r)->r_bustag = (t))
+#define rman_get_bustag(r) ((r)->r_bustag)
+#define rman_set_bushandle(r,h) ((r)->r_bushandle = (h))
+#define rman_get_bushandle(r) ((r)->r_bushandle)
extern struct rman_head rman_head;
#endif /* KERNEL */
OpenPOWER on IntegriCloud