Factor out the object system from new-bus so that it can be used by
authorJeroen Ruigrok/asmodai <asmodai@dragonflybsd.org>
Mon, 17 Nov 2003 00:54:40 +0000 (00:54 +0000)
committerJeroen Ruigrok/asmodai <asmodai@dragonflybsd.org>
Mon, 17 Nov 2003 00:54:40 +0000 (00:54 +0000)
non-device code.

Re-implement the method dispatch to improve efficiency. The new system
takes about 40ns for a method dispatch on a 300Mhz PII which is only 10ns
slower than a direct function call on the same hardware.

This is all based on Doug Rabson's work in April and May of 2000.

16 files changed:
sys/bus/iicbus/iicbb_if.m
sys/bus/iicbus/iicbus_if.m
sys/bus/isa/i386/isa_compat.c
sys/bus/isa/isa_if.m
sys/bus/pci/pci.c
sys/bus/pci/pci_if.m
sys/bus/smbus/smbus_if.m
sys/conf/Makefile.i386
sys/conf/kmod.mk
sys/dev/misc/dec/mcclock_if.m
sys/dev/netif/mii_layer/miibus_if.m
sys/kern/bus_if.m
sys/kern/device_if.m
sys/kern/subr_bus.c
sys/sys/bus.h
sys/sys/bus_private.h

index 946b29a..9d88298 100644 (file)
 # SUCH DAMAGE.
 #
 # $FreeBSD: src/sys/dev/iicbus/iicbb_if.m,v 1.3 1999/08/28 00:41:58 peter Exp $
-# $DragonFly: src/sys/bus/iicbus/iicbb_if.m,v 1.2 2003/06/17 04:28:27 dillon Exp $
+# $DragonFly: src/sys/bus/iicbus/iicbb_if.m,v 1.3 2003/11/17 00:54:39 asmodai Exp $
 #
 
+#include <sys/bus.h>
+
 INTERFACE iicbb;
 
 #
index fce244c..7e9f32e 100644 (file)
 # SUCH DAMAGE.
 #
 # $FreeBSD: src/sys/dev/iicbus/iicbus_if.m,v 1.4 1999/08/28 00:41:59 peter Exp $
-# $DragonFly: src/sys/bus/iicbus/iicbus_if.m,v 1.2 2003/06/17 04:28:27 dillon Exp $
+# $DragonFly: src/sys/bus/iicbus/iicbus_if.m,v 1.3 2003/11/17 00:54:39 asmodai Exp $
 #
 
+#include <sys/bus.h>
+
 INTERFACE iicbus;
 
 #
index afe124e..5fe74b9 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/i386/isa/isa_compat.c,v 1.18.2.1 2001/05/17 23:05:06 imp Exp $
- * $DragonFly: src/sys/bus/isa/i386/isa_compat.c,v 1.3 2003/08/07 21:16:46 dillon Exp $
+ * $DragonFly: src/sys/bus/isa/i386/isa_compat.c,v 1.4 2003/11/17 00:54:39 asmodai Exp $
  */
 
 #include <sys/param.h>
@@ -290,7 +290,7 @@ isa_wrap_old_drivers(void)
                bzero(driver, sizeof(driver_t));
                driver->name = op->driver->name;
                driver->methods = isa_compat_methods;
-               driver->softc = sizeof(struct isa_device);
+               driver->size = sizeof(struct isa_device);
                driver->priv = op;
                if (op->driver->sensitive_hw)
                        resource_set_int(op->driver->name, -1, "sensitive", 1);
index 1656d54..70ac276 100644 (file)
 # SUCH DAMAGE.
 #
 # $FreeBSD: src/sys/isa/isa_if.m,v 1.5 1999/10/12 21:35:48 dfr Exp $
-# $DragonFly: src/sys/bus/isa/isa_if.m,v 1.3 2003/08/07 21:16:46 dillon Exp $
+# $DragonFly: src/sys/bus/isa/isa_if.m,v 1.4 2003/11/17 00:54:39 asmodai Exp $
 #
 
-CODE {
+#include <sys/bus.h>
 #include <bus/isa/isavar.h>
-};
 
 INTERFACE isa;
 
index 1a947bb..61e5d49 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/pci/pci.c,v 1.141.2.15 2002/04/30 17:48:18 tmm Exp $
- * $DragonFly: src/sys/bus/pci/pci.c,v 1.5 2003/08/07 21:16:47 dillon Exp $
+ * $DragonFly: src/sys/bus/pci/pci.c,v 1.6 2003/11/17 00:54:39 asmodai Exp $
  *
  */
 
@@ -1177,7 +1177,7 @@ compat_pci_handler(module_t mod, int type, void *data)
                bzero(driver, sizeof(driver_t));
                driver->name = dvp->pd_name;
                driver->methods = pci_compat_methods;
-               driver->softc = sizeof(struct pci_devinfo *);
+               driver->size = sizeof(struct pci_devinfo *);
                driver->priv = dvp;
                devclass_add_driver(pci_devclass, driver);
                break;
index 7a3b895..1c5e92a 100644 (file)
 # SUCH DAMAGE.
 #
 # $FreeBSD: src/sys/pci/pci_if.m,v 1.2.2.1 2001/07/21 22:40:26 imp Exp $
-# $DragonFly: src/sys/bus/pci/pci_if.m,v 1.2 2003/06/17 04:28:57 dillon Exp $
+# $DragonFly: src/sys/bus/pci/pci_if.m,v 1.3 2003/11/17 00:54:39 asmodai Exp $
 #
 
+#include <sys/bus.h>
+
 INTERFACE pci;
 
 METHOD u_int32_t read_config {
index 88d2876..f1bece3 100644 (file)
 # SUCH DAMAGE.
 #
 # $FreeBSD: src/sys/dev/smbus/smbus_if.m,v 1.5 1999/08/28 00:42:30 peter Exp $
-# $DragonFly: src/sys/bus/smbus/smbus_if.m,v 1.2 2003/06/17 04:28:29 dillon Exp $
+# $DragonFly: src/sys/bus/smbus/smbus_if.m,v 1.3 2003/11/17 00:54:39 asmodai Exp $
 #
 
+#include <sys/bus.h>
+
 INTERFACE smbus;
 
 #
index 0f1e1e4..2fc328d 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright 1990 W. Jolitz
 #      from: @(#)Makefile.i386 7.1 5/10/91
 # $FreeBSD: src/sys/conf/Makefile.i386,v 1.179.2.16 2002/11/18 11:26:49 ru Exp $
-# $DragonFly: src/sys/conf/Attic/Makefile.i386,v 1.10 2003/11/16 22:27:49 dillon Exp $
+# $DragonFly: src/sys/conf/Attic/Makefile.i386,v 1.11 2003/11/17 00:54:39 asmodai Exp $
 #
 # Makefile for FreeBSD
 #
@@ -84,7 +84,7 @@ NORMAL_C_C= ${CC} -c ${CFLAGS} ${PROF} ${.IMPSRC}
 NORMAL_S= ${CC} -c ${ASM_CFLAGS} ${.IMPSRC}
 PROFILE_C= ${CC} -c ${CFLAGS} ${.IMPSRC}
 
-NORMAL_M= perl5 $S/kern/makedevops.pl -c $<; \
+NORMAL_M= perl5 $S/kern/makeobjops.pl -c $<; \
        ${CC} -c ${CFLAGS} ${PROF} ${.PREFIX}.c
 
 GEN_CFILES= $S/$M/$M/genassym.c
@@ -142,7 +142,7 @@ ${SYSTEM_OBJS}: vnode_if.h ${BEFORE_DEPEND:M*.h} ${MFILES:T:S/.m$/.h/}
 
 .for mfile in ${MFILES}
 ${mfile:T:S/.m$/.h/}: ${mfile}
-       perl5 $S/kern/makedevops.pl -h ${mfile}
+       perl5 $S/kern/makeobjops.pl -h ${mfile}
 .endfor
 
 kernel-clean:
index 1ad235f..6af4104 100644 (file)
@@ -1,6 +1,6 @@
 #      From: @(#)bsd.prog.mk   5.26 (Berkeley) 6/25/91
 # $FreeBSD: src/sys/conf/kmod.mk,v 1.82.2.15 2003/02/10 13:11:50 nyan Exp $
-# $DragonFly: src/sys/conf/kmod.mk,v 1.7 2003/11/15 19:01:27 dillon Exp $
+# $DragonFly: src/sys/conf/kmod.mk,v 1.8 2003/11/17 00:54:39 asmodai Exp $
 #
 # The include file <bsd.kmod.mk> handles installing Kernel Loadable Device
 # drivers (KLD's).
@@ -232,9 +232,9 @@ CLEANFILES+=        ${_src}
 .if !target(${_src})
 ${_src}: @
 .if exists(@)
-${_src}: @/kern/makeops.pl @/${_srcsrc}
+${_src}: @/kern/makeobjops.pl @/${_srcsrc}
 .endif
-       perl @/kern/makeops.pl -${_ext} @/${_srcsrc}
+       perl @/kern/makeobjops.pl -${_ext} @/${_srcsrc}
 .endif
 .endfor # _src
 .endfor # _ext
index 92d7344..babf186 100644 (file)
 # SUCH DAMAGE.
 #
 # $FreeBSD: src/sys/dev/dec/mcclock_if.m,v 1.3 1999/08/28 00:41:37 peter Exp $
-# $DragonFly: src/sys/dev/misc/dec/Attic/mcclock_if.m,v 1.2 2003/06/17 04:28:23 dillon Exp $
+# $DragonFly: src/sys/dev/misc/dec/Attic/mcclock_if.m,v 1.3 2003/11/17 00:54:39 asmodai Exp $
 #
 
+#include <sys/bus.h>
+
 INTERFACE mcclock;
 
 #
index 88bb8d2..3e6f01b 100644 (file)
@@ -1,5 +1,7 @@
 # $FreeBSD: src/sys/dev/mii/miibus_if.m,v 1.2 1999/08/28 00:42:14 peter Exp $
-# $DragonFly: src/sys/dev/netif/mii_layer/miibus_if.m,v 1.2 2003/06/17 04:28:28 dillon Exp $
+# $DragonFly: src/sys/dev/netif/mii_layer/miibus_if.m,v 1.3 2003/11/17 00:54:40 asmodai Exp $
+
+#include <sys/bus.h>
 
 INTERFACE miibus;
 
index 87902dc..a370d73 100644 (file)
 # SUCH DAMAGE.
 #
 # $FreeBSD: src/sys/kern/bus_if.m,v 1.16 1999/10/12 21:35:50 dfr Exp $
-# $DragonFly: src/sys/kern/bus_if.m,v 1.2 2003/06/17 04:28:41 dillon Exp $
+# $DragonFly: src/sys/kern/bus_if.m,v 1.3 2003/11/17 00:54:40 asmodai Exp $
 #
 
+#include <sys/bus.h>
+
 INTERFACE bus;
 
 #
index c5f09b7..8f323fd 100644 (file)
 # SUCH DAMAGE.
 #
 # $FreeBSD: src/sys/kern/device_if.m,v 1.7.2.1 2001/07/24 09:49:41 dd Exp $
-# $DragonFly: src/sys/kern/device_if.m,v 1.2 2003/06/17 04:28:41 dillon Exp $
+# $DragonFly: src/sys/kern/device_if.m,v 1.3 2003/11/17 00:54:40 asmodai Exp $
 #
 
+#include <sys/bus.h>
+
 INTERFACE device;
 
 #
index a33e842..466592f 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/subr_bus.c,v 1.54.2.9 2002/10/10 15:13:32 jhb Exp $
- * $DragonFly: src/sys/kern/subr_bus.c,v 1.4 2003/11/09 02:22:36 dillon Exp $
+ * $DragonFly: src/sys/kern/subr_bus.c,v 1.5 2003/11/17 00:54:40 asmodai Exp $
  */
 
 #include "opt_bus.h"
@@ -37,6 +37,7 @@
 #ifdef DEVICE_SYSCTLS
 #include <sys/sysctl.h>
 #endif
+#include <sys/kobj.h>
 #include <sys/bus_private.h>
 #include <sys/systm.h>
 #include <machine/bus.h>
@@ -56,8 +57,6 @@ MALLOC_DEFINE(M_BUS, "bus", "Bus data structures");
  */
 #define indentprintf(p)        do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf("  "); printf p ; } while(0)
 
-static void print_method_list(device_method_t *m, int indent);
-static void print_device_ops(device_ops_t ops, int indent);
 static void print_device_short(device_t dev, int indent);
 static void print_device(device_t dev, int indent);
 void print_device_tree_short(device_t dev, int indent);
@@ -77,8 +76,6 @@ void print_devclass_list(void);
 #define DRIVERNAME(d)                  /* nop */
 #define DEVCLANAME(d)                  /* nop */
 
-#define print_method_list(m,i)         /* nop */
-#define print_device_ops(o,i)          /* nop */
 #define print_device_short(d,i)                /* nop */
 #define print_device(d,i)              /* nop */
 #define print_device_tree_short(d,i)   /* nop */
@@ -97,146 +94,11 @@ static void device_register_oids(device_t dev);
 static void device_unregister_oids(device_t dev);
 #endif
 
-/*
- * Method table handling
- */
-static int error_method(void);
-static int next_method_offset = 1;
-
-LIST_HEAD(methodlist, method) methods;
-struct method {
-    LIST_ENTRY(method) link;   /* linked list of methods */
-    int offset;                        /* offset in method table */
-    int refs;                  /* count of device_op_desc users */
-    devop_t deflt;             /* default implementation */
-    char* name;                        /* unique name of method */
-};
-
-static void
-register_method(struct device_op_desc *desc)
-{
-    struct method* m;
-
-    if (desc->method) {
-       desc->method->refs++;
-       return;
-    }
-
-    /*
-     * Make sure that desc->deflt is always valid to simplify dispatch.
-     */
-    if (!desc->deflt)
-       desc->deflt = error_method;
-
-    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(("method %p has the same name, %s, with offset %d",
-                   (void *)m, desc->name, desc->offset));
-           return;
-       }
-    }
-
-    m = (struct method *) malloc(sizeof(struct method)
-                                + strlen(desc->name) + 1,
-                                M_BUS, 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->deflt = desc->deflt;
-    m->name = (char*) (m + 1);
-    strcpy(m->name, desc->name);
-    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) {
-       PDEBUG(("method %s, reached refcount 0", desc->name));
-       LIST_REMOVE(m, link);
-       free(m, M_BUS);
-       desc->method = 0;
-    }
-}
-
-static int error_method(void)
-{
-    return ENXIO;
-}
-
-static struct device_ops null_ops = {
-    1, 
-    { error_method }
+kobj_method_t null_methods[] = {
+    { 0, 0 }
 };
 
-static void
-compile_methods(driver_t *driver)
-{
-    device_ops_t ops;
-    struct device_method *m;
-    struct method *cm;
-    int i;
-
-    /*
-     * First register any methods which need it.
-     */
-    for (i = 0, m = driver->methods; m->desc; i++, m++)
-       register_method(m->desc);
-
-    /*
-     * Then allocate the compiled op table.
-     */
-    ops = malloc(sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t),
-                M_BUS, 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;
-    /* Fill in default methods and then overwrite with driver methods */
-    for (i = 0; i < next_method_offset; i++)
-       ops->methods[i] = error_method;
-    for (cm = LIST_FIRST(&methods); cm; cm = LIST_NEXT(cm, link)) {
-       if (cm->deflt)
-           ops->methods[cm->offset] = cm->deflt;
-    }
-    for (i = 0, m = driver->methods; m->desc; i++, m++)
-       ops->methods[m->desc->offset] = m->func;
-    PDEBUG(("%s has %d method%s, wasting %d bytes",
-               DRIVERNAME(driver), i, (i==1?"":"s"),
-               (next_method_offset-i)*sizeof(devop_t)));
-
-    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_BUS);
-    driver->ops = 0;
-}
+DEFINE_CLASS(null, null_methods, 0);
 
 /*
  * Devclass implementation
@@ -301,10 +163,12 @@ devclass_add_driver(devclass_t dc, driver_t *driver)
     bzero(dl, sizeof *dl);
 
     /*
-     * Compile the driver's methods.
+     * Compile the driver's methods. Also increase the reference count
+     * so that the class doesn't get freed when the last instance
+     * goes. This means we can safely use static methods and avoids a
+     * double-free in devclass_delete_driver.
      */
-    if (!driver->ops)
-       compile_methods(driver);
+    kobj_class_compile((kobj_class_t) driver);
 
     /*
      * Make sure the devclass which the driver is implementing exists.
@@ -380,7 +244,7 @@ devclass_delete_driver(devclass_t busclass, driver_t *driver)
 
     driver->refs--;
     if (driver->refs == 0)
-       free_methods(driver);
+       kobj_class_free((kobj_class_t) driver);
 
     return 0;
 }
@@ -604,7 +468,7 @@ make_device(device_t parent, const char *name, int unit)
 
     dev->parent = parent;
     TAILQ_INIT(&dev->children);
-    dev->ops = &null_ops;
+    kobj_init((kobj_t) dev, &null_class);
     dev->driver = NULL;
     dev->devclass = NULL;
     dev->unit = unit;
@@ -625,6 +489,8 @@ make_device(device_t parent, const char *name, int unit)
 
     dev->state = DS_NOTPRESENT;
 
+    kobj_init((kobj_t) dev, &null_class);
+
     return dev;
 }
 
@@ -1125,19 +991,20 @@ device_set_driver(device_t dev, driver_t *driver)
        free(dev->softc, M_BUS);
        dev->softc = NULL;
     }
-    dev->ops = &null_ops;
+    kobj_delete((kobj_t) dev, 0);
     dev->driver = driver;
     if (driver) {
-       dev->ops = driver->ops;
+       kobj_init((kobj_t) dev, (kobj_class_t) driver);
        if (!(dev->flags & DF_EXTERNALSOFTC)) {
-           dev->softc = malloc(driver->softc, M_BUS, M_NOWAIT);
+           dev->softc = malloc(driver->size, M_BUS, M_NOWAIT);
            if (!dev->softc) {
-               dev->ops = &null_ops;
+               kobj_init((kobj_t) dev, &null_class);
                dev->driver = NULL;
                return ENOMEM;
            }
-           bzero(dev->softc, driver->softc);
-       }
+           bzero(dev->softc, driver->size);
+       } else
+           kobj_init((kobj_t) dev, &null_class);
     }
     return 0;
 }
@@ -2228,17 +2095,17 @@ root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg,
        panic("root_setup_intr");
 }
 
-static device_method_t root_methods[] = {
+static kobj_method_t root_methods[] = {
        /* Device interface */
-       DEVMETHOD(device_shutdown,      bus_generic_shutdown),
-       DEVMETHOD(device_suspend,       bus_generic_suspend),
-       DEVMETHOD(device_resume,        bus_generic_resume),
+       KOBJMETHOD(device_shutdown,     bus_generic_shutdown),
+       KOBJMETHOD(device_suspend,      bus_generic_suspend),
+       KOBJMETHOD(device_resume,       bus_generic_resume),
 
        /* Bus interface */
-       DEVMETHOD(bus_print_child,      root_print_child),
-       DEVMETHOD(bus_read_ivar,        bus_generic_read_ivar),
-       DEVMETHOD(bus_write_ivar,       bus_generic_write_ivar),
-       DEVMETHOD(bus_setup_intr,       root_setup_intr),
+       KOBJMETHOD(bus_print_child,     root_print_child),
+       KOBJMETHOD(bus_read_ivar,       bus_generic_read_ivar),
+       KOBJMETHOD(bus_write_ivar,      bus_generic_write_ivar),
+       KOBJMETHOD(bus_setup_intr,      root_setup_intr),
 
        { 0, 0 }
 };
@@ -2257,10 +2124,10 @@ root_bus_module_handler(module_t mod, int what, void* arg)
 {
     switch (what) {
     case MOD_LOAD:
-       compile_methods(&root_driver);
+       kobj_class_compile((kobj_class_t) &root_driver);
        root_bus = make_device(NULL, "root", 0);
        root_bus->desc = "System root bus";
-       root_bus->ops = root_driver.ops;
+       kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver);
        root_bus->driver = &root_driver;
        root_bus->state = DS_ATTACHED;
        root_devclass = devclass_find_internal("root", FALSE);
@@ -2352,49 +2219,6 @@ driver_module_handler(module_t mod, int what, void *arg)
  * more than oneliners. I love oneliners.
  */
 
-static void
-print_method_list(device_method_t *m, int indent)
-{
-       int i;
-
-       if (!m)
-               return;
-
-       for (i = 0; m->desc; i++, m++)
-               indentprintf(("method %d: %s, offset=%d\n",
-                       i, m->desc->name, m->desc->offset));
-}
-
-static void
-print_device_ops(device_ops_t ops, int indent)
-{
-       int i;
-       int count = 0;
-
-       if (!ops)
-               return;
-
-       /* we present a list of the methods that are pointing to the
-        * error_method, but ignore the 0'th elements; it is always
-        * error_method.
-        */
-       for (i = 1; i < ops->maxoffset; i++) {
-               if (ops->methods[i] == error_method) {
-                       if (count == 0)
-                               indentprintf(("error_method:"));
-                       printf(" %d", i);
-                       count++;
-               }
-       }
-       if (count)
-               printf("\n");
-
-       indentprintf(("(%d method%s, %d valid, %d error_method%s)\n",
-               ops->maxoffset-1, (ops->maxoffset-1 == 1? "":"s"),
-               ops->maxoffset-1-count,
-               count, (count == 1? "":"'s")));
-}
-
 static void
 print_device_short(device_t dev, int indent)
 {
@@ -2424,8 +2248,6 @@ print_device(device_t dev, int indent)
 
        indentprintf(("Parent:\n"));
        print_device_short(dev->parent, indent+1);
-       indentprintf(("Methods:\n"));
-       print_device_ops(dev->ops, indent+1);
        indentprintf(("Driver:\n"));
        print_driver_short(dev->driver, indent+1);
        indentprintf(("Devclass:\n"));
@@ -2471,7 +2293,7 @@ print_driver_short(driver_t *driver, int indent)
                return;
 
        indentprintf(("driver %s: softc size = %d\n",
-               driver->name, driver->softc));
+               driver->name, driver->size));
 }
 
 static void
@@ -2481,10 +2303,6 @@ print_driver(driver_t *driver, int indent)
                return;
 
        print_driver_short(driver, indent);
-       indentprintf(("Methods:\n"));
-       print_method_list(driver->methods, indent+1);
-       indentprintf(("Operations:\n"));
-       print_device_ops(driver->ops, indent+1);
 }
 
 
index 9afe08b..7ec2ae4 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/bus.h,v 1.30.2.4 2002/10/10 15:13:33 jhb Exp $
- * $DragonFly: src/sys/sys/bus.h,v 1.2 2003/06/17 04:28:58 dillon Exp $
+ * $DragonFly: src/sys/sys/bus.h,v 1.3 2003/11/17 00:54:40 asmodai Exp $
  */
 
 #ifndef _SYS_BUS_H_
 #ifdef _KERNEL
 
 #include <sys/queue.h>
+#include <sys/kobj.h>
 
 /*
  * Forward declarations
  */
 typedef struct device          *device_t;
 typedef struct driver          driver_t;
-typedef struct device_method   device_method_t;
 typedef struct devclass                *devclass_t;
-typedef struct device_ops      *device_ops_t;
-typedef struct device_op_desc  *device_op_desc_t;
+#define        device_method_t         kobj_method_t
 
 typedef void driver_intr_t(void*);
 
@@ -65,18 +64,9 @@ enum intr_type {
 
 typedef int (*devop_t)(void);
 
-struct device_method {
-    device_op_desc_t   desc;
-    devop_t            func;
-};
-
 struct driver {
-    const char         *name;          /* driver name */
-    device_method_t    *methods;       /* method table */
-    size_t             softc;          /* size of device softc struct */
+    KOBJ_CLASS_FIELDS;
     void               *priv;          /* driver private data */
-    device_ops_t       ops;            /* compiled method table */
-    int                        refs;           /* # devclasses containing driver */
 };
 
 typedef enum device_state {
@@ -313,7 +303,7 @@ int resource_count(void);
 /*
  * Shorthand for constructing method tables.
  */
-#define DEVMETHOD(NAME, FUNC) { &NAME##_desc, (devop_t) FUNC }
+#define DEVMETHOD      KOBJMETHOD
 
 /*
  * Some common device interfaces.
index 8a16416..b9c21ae 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/sys/bus_private.h,v 1.11.2.2 2000/08/03 00:25:22 peter Exp $
- * $DragonFly: src/sys/sys/bus_private.h,v 1.2 2003/06/17 04:28:58 dillon Exp $
+ * $DragonFly: src/sys/sys/bus_private.h,v 1.3 2003/11/17 00:54:40 asmodai Exp $
  */
 
 #ifndef _SYS_BUS_PRIVATE_H_
@@ -80,35 +80,16 @@ struct config_device {
     struct config_resource     *resources;
 };
 
-/*
- * Compiled device methods.
- */
-struct device_ops {
-    int maxoffset;
-    devop_t methods[1];
-};
-
-/*
- * Helpers for device method wrappers.
- */
-#define DEVOPDESC(OP)  (&OP##_##desc)
-
-#define DEVOPS(DEV)       (DEV->ops)
-#define DEVOPMETH(DEV, OP)                                     \
-       ((DEVOPDESC(OP)->offset >= DEVOPS(DEV)->maxoffset)      \
-        ? DEVOPDESC(OP)->deflt                                 \
-        : DEVOPS(DEV)->methods[DEVOPDESC(OP)->offset])
-
-#define DRVOPS(DRV)       ((struct device_ops *)DRV->ops)
-#define DRVOPMETH(DRV, OP)                                     \
-       ((DEVOPDESC(OP)->offset >= DRVOPS(DRV)->maxoffset)      \
-        ? DEVOPDESC(OP)->deflt                                 \
-        : DRVOPS(DRV)->methods[DEVOPDESC(OP)->offset])
-
 /*
  * Implementation of device.
  */
 struct device {
+    /*
+     * A device is a kernel object. The first field must be the
+     * current ops table for the object.
+     */
+    KOBJ_FIELDS;
+
     /*
      * Device hierarchy.
      */
@@ -119,7 +100,6 @@ struct device {
     /*
      * Details of this device.
      */
-    device_ops_t       ops;
     driver_t           *driver;
     devclass_t         devclass; /* device class which we are in */
     int                        unit;