summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>1999-03-29 08:54:20 +0000
committerdfr <dfr@FreeBSD.org>1999-03-29 08:54:20 +0000
commite92e9c75bfcb1d32e9a6da832e0288caef0abd4a (patch)
treed56b9573f9c1710544ea3b0ac9249a916228c0ed /sys
parent21b8cdbbc44555e6e72a62f039cb74083fa94385 (diff)
downloadFreeBSD-src-e92e9c75bfcb1d32e9a6da832e0288caef0abd4a.zip
FreeBSD-src-e92e9c75bfcb1d32e9a6da832e0288caef0abd4a.tar.gz
Add some useful functions to the device framework:
* bus_setup_intr() as a wrapper for BUS_SETUP_INTR * bus_teardown_intr() as a wrapper for BUS_TEARDOWN_INTR * device_get_nameunit() which returns e.g. "foo0" for name "foo" and unit 0. * device_set_desc_copy() malloc a copy of the description string. * device_quiet(), device_is_quiet(), device_verbose() suppress probe message. Add one method to the BUS interface, BUS_CHILD_DETACHED() which is called after the child has been detached to allow the bus to clean up any memory which it allocated on behalf of the child. I also fixed a bug which corrupted the list of drivers in a devclass if a driver was added to more than one devclass.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/bus_if.m11
-rw-r--r--sys/kern/makedevops.pl1
-rw-r--r--sys/kern/subr_bus.c345
-rw-r--r--sys/sys/bus.h13
-rw-r--r--sys/sys/bus_private.h22
5 files changed, 343 insertions, 49 deletions
diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m
index fd4f648..8c48082 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.4 1998/11/08 18:51:38 nsouch Exp $
+# $Id: bus_if.m,v 1.5 1998/11/14 21:58:51 wollman Exp $
#
INTERFACE bus;
@@ -71,6 +71,15 @@ METHOD int write_ivar {
};
#
+# Called after the child's DEVICE_DETACH method to allow the parent
+# to reclaim any resources allocated on behalf of the child.
+#
+METHOD void child_detached {
+ device_t dev;
+ device_t child;
+};
+
+#
# 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 a542dcd..1c434d5 100644
--- a/sys/kern/makedevops.pl
+++ b/sys/kern/makedevops.pl
@@ -153,6 +153,7 @@ foreach $src ( @filenames ) {
print CFILE "\n";
print CFILE "#include <sys/param.h>\n";
print CFILE "#include <sys/queue.h>\n";
+ print CFILE "#include <sys/sysctl.h>\n";
print CFILE "#include <sys/bus_private.h>\n";
}
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 283dd60..4469b70 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.14 1999/01/16 17:44:09 dfr Exp $
+ * $Id: subr_bus.c,v 1.15 1999/01/27 21:49:57 dillon Exp $
*/
#include <sys/param.h>
@@ -31,6 +31,7 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/sysctl.h>
#include <sys/bus_private.h>
#include <sys/systm.h>
#include <machine/stdarg.h> /* for device_printf() */
@@ -84,6 +85,10 @@ void print_devclass_list(void);
#define print_devclass_list() /* nop */
#endif
+#ifdef DEVICE_SYSCTLS
+static void device_register_oids(device_t dev);
+static void device_unregister_oids(device_t dev);
+#endif
/*
* Method table handling
@@ -227,7 +232,14 @@ devclass_find(const char *classname)
int
devclass_add_driver(devclass_t dc, driver_t *driver)
{
+ driverlink_t dl;
+
PDEBUG(("%s", DRIVERNAME(driver)));
+
+ dl = malloc(sizeof *dl, M_DEVBUF, M_NOWAIT);
+ if (!dl)
+ return ENOMEM;
+
/*
* Compile the drivers methods.
*/
@@ -238,7 +250,8 @@ devclass_add_driver(devclass_t dc, driver_t *driver)
*/
devclass_find_internal(driver->name, TRUE);
- TAILQ_INSERT_TAIL(&dc->drivers, driver, link);
+ dl->driver = driver;
+ TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
return 0;
}
@@ -247,6 +260,7 @@ int
devclass_delete_driver(devclass_t busclass, driver_t *driver)
{
devclass_t dc = devclass_find(driver->name);
+ driverlink_t dl;
device_t dev;
int i;
int error;
@@ -257,14 +271,34 @@ devclass_delete_driver(devclass_t busclass, driver_t *driver)
return 0;
/*
+ * Find the link structure in the bus' list of drivers.
+ */
+ for (dl = TAILQ_FIRST(&busclass->drivers); dl;
+ dl = TAILQ_NEXT(dl, link)) {
+ if (dl->driver == driver)
+ break;
+ }
+
+ if (!dl) {
+ PDEBUG(("%s not found in %s list", driver->name, busclass->name));
+ return ENOENT;
+ }
+
+ /*
* Disassociate from any devices. We iterate through all the
* devices in the devclass of the driver and detach any which are
- * using the driver.
+ * using the driver and which have a parent in the devclass which
+ * we are deleting from.
+ *
+ * Note that since a driver can be in multiple devclasses, we
+ * should not detach devices which are not children of devices in
+ * the affected devclass.
*/
for (i = 0; i < dc->maxunit; i++) {
if (dc->devices[i]) {
dev = dc->devices[i];
- if (dev->driver == driver) {
+ if (dev->driver == driver
+ && dev->parent && dev->parent->devclass == busclass) {
if ((error = device_detach(dev)) != 0)
return error;
device_set_driver(dev, NULL);
@@ -272,27 +306,40 @@ devclass_delete_driver(devclass_t busclass, driver_t *driver)
}
}
- TAILQ_REMOVE(&busclass->drivers, driver, link);
+ TAILQ_REMOVE(&busclass->drivers, dl, link);
+ free(dl, M_DEVBUF);
+
return 0;
}
-driver_t *
-devclass_find_driver(devclass_t dc, const char *classname)
+static driverlink_t
+devclass_find_driver_internal(devclass_t dc, const char *classname)
{
- driver_t *driver;
+ driverlink_t dl;
PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc)));
- for (driver = TAILQ_FIRST(&dc->drivers); driver;
- driver = TAILQ_NEXT(driver, link)) {
- if (!strcmp(driver->name, classname))
- return driver;
+ for (dl = TAILQ_FIRST(&dc->drivers); dl; dl = TAILQ_NEXT(dl, link)) {
+ if (!strcmp(dl->driver->name, classname))
+ return dl;
}
PDEBUG(("not found"));
return NULL;
}
+driver_t *
+devclass_find_driver(devclass_t dc, const char *classname)
+{
+ driverlink_t dl;
+
+ dl = devclass_find_driver_internal(dc, classname);
+ if (dl)
+ return dl->driver;
+ else
+ return NULL;
+}
+
const char *
devclass_get_name(devclass_t dc)
{
@@ -407,14 +454,28 @@ devclass_alloc_unit(devclass_t dc, int *unitp)
static int
devclass_add_device(devclass_t dc, device_t dev)
{
- int error;
+ int buflen, error;
PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
- if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0)
+ buflen = strlen(dc->name) + 5;
+ dev->nameunit = malloc(buflen, M_DEVBUF, M_NOWAIT);
+ if (!dev->nameunit)
+ return ENOMEM;
+
+ if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) {
+ free(dev->nameunit, M_DEVBUF);
+ dev->nameunit = NULL;
return error;
+ }
dc->devices[dev->unit] = dev;
dev->devclass = dc;
+ snprintf(dev->nameunit, buflen, "%s%d", dc->name, dev->unit);
+
+#ifdef DEVICE_SYSCTLS
+ device_register_oids(dev);
+#endif
+
return 0;
}
@@ -433,8 +494,15 @@ devclass_delete_device(devclass_t dc, device_t dev)
if (dev->flags & DF_WILDCARD)
dev->unit = -1;
dev->devclass = NULL;
+ free(dev->nameunit, M_DEVBUF);
+ dev->nameunit = NULL;
while (dc->nextunit > 0 && dc->devices[dc->nextunit - 1] == NULL)
dc->nextunit--;
+
+#ifdef DEVICE_SYSCTLS
+ device_unregister_oids(dev);
+#endif
+
return 0;
}
@@ -444,7 +512,6 @@ make_device(device_t parent, const char *name,
{
device_t dev;
devclass_t dc;
- int error;
PDEBUG(("%s at %s as unit %d with%s ivars",
name, DEVICENAME(parent), unit, (ivars? "":"out")));
@@ -455,9 +522,6 @@ make_device(device_t parent, const char *name,
printf("make_device: can't find device class %s\n", name);
return NULL;
}
-
- if ((error = devclass_alloc_unit(dc, &unit)) != 0)
- return NULL;
} else
dc = NULL;
@@ -469,21 +533,21 @@ make_device(device_t parent, const char *name,
TAILQ_INIT(&dev->children);
dev->ops = &null_ops;
dev->driver = NULL;
- dev->devclass = dc;
+ dev->devclass = NULL;
dev->unit = unit;
+ dev->nameunit = NULL;
dev->desc = NULL;
dev->busy = 0;
dev->flags = DF_ENABLED;
if (unit == -1)
dev->flags |= DF_WILDCARD;
- if (name)
+ if (name) {
dev->flags |= DF_FIXEDCLASS;
+ devclass_add_device(dc, dev);
+ }
dev->ivars = ivars;
dev->softc = NULL;
- if (dc)
- dc->devices[unit] = dev;
-
dev->state = DS_NOTPRESENT;
return dev;
@@ -560,6 +624,7 @@ device_delete_child(device_t dev, device_t child)
if (child->devclass)
devclass_delete_device(child->devclass, child);
TAILQ_REMOVE(&dev->children, child, link);
+ device_set_desc(child, NULL);
free(child, M_DEVBUF);
return 0;
@@ -584,24 +649,23 @@ device_find_child(device_t dev, const char *classname, int unit)
return NULL;
}
-static driver_t *
+static driverlink_t
first_matching_driver(devclass_t dc, device_t dev)
{
if (dev->devclass)
- return devclass_find_driver(dc, dev->devclass->name);
+ return devclass_find_driver_internal(dc, dev->devclass->name);
else
return TAILQ_FIRST(&dc->drivers);
}
-static driver_t *
-next_matching_driver(devclass_t dc, device_t dev, driver_t *last)
+static driverlink_t
+next_matching_driver(devclass_t dc, device_t dev, driverlink_t last)
{
if (dev->devclass) {
- driver_t *driver;
- for (driver = TAILQ_NEXT(last, link); driver;
- driver = TAILQ_NEXT(driver, link))
- if (!strcmp(dev->devclass->name, driver->name))
- return driver;
+ driverlink_t dl;
+ for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link))
+ if (!strcmp(dev->devclass->name, dl->driver->name))
+ return dl;
return NULL;
} else
return TAILQ_NEXT(last, link);
@@ -611,7 +675,7 @@ static int
device_probe_child(device_t dev, device_t child)
{
devclass_t dc;
- driver_t *driver;
+ driverlink_t dl;
dc = dev->devclass;
if (dc == NULL)
@@ -620,14 +684,14 @@ device_probe_child(device_t dev, device_t child)
if (child->state == DS_ALIVE)
return 0;
- for (driver = first_matching_driver(dc, child);
- driver;
- driver = next_matching_driver(dc, child, driver)) {
- PDEBUG(("Trying %s", DRIVERNAME(driver)));
- device_set_driver(child, driver);
+ for (dl = first_matching_driver(dc, child);
+ dl;
+ dl = next_matching_driver(dc, child, dl)) {
+ PDEBUG(("Trying %s", DRIVERNAME(dl->driver)));
+ device_set_driver(child, dl->driver);
if (DEVICE_PROBE(child) == 0) {
if (!child->devclass)
- device_set_devclass(child, driver->name);
+ device_set_devclass(child, dl->driver->name);
child->state = DS_ALIVE;
return 0;
}
@@ -691,6 +755,12 @@ device_get_name(device_t dev)
return NULL;
}
+const char *
+device_get_nameunit(device_t dev)
+{
+ return dev->nameunit;
+}
+
int
device_get_unit(device_t dev)
{
@@ -724,10 +794,44 @@ device_printf(device_t dev, const char * fmt, ...)
va_end(ap);
}
+static void
+device_set_desc_internal(device_t dev, const char* desc, int copy)
+{
+ if (dev->desc && (dev->flags & DF_DESCMALLOCED)) {
+ free(dev->desc, M_DEVBUF);
+ dev->flags &= ~DF_DESCMALLOCED;
+ dev->desc = NULL;
+ }
+
+ if (copy && desc) {
+ dev->desc = malloc(strlen(desc) + 1, M_DEVBUF, M_NOWAIT);
+ if (dev->desc) {
+ strcpy(dev->desc, desc);
+ dev->flags |= DF_DESCMALLOCED;
+ }
+ } else
+ /* Avoid a -Wcast-qual warning */
+ dev->desc = (char *)(uintptr_t) desc;
+
+#ifdef DEVICE_SYSCTLS
+ {
+ struct sysctl_oid *oid = &dev->oid[1];
+ oid->oid_arg1 = dev->desc ? dev->desc : "";
+ oid->oid_arg2 = dev->desc ? strlen(dev->desc) : 0;
+ }
+#endif
+}
+
void
device_set_desc(device_t dev, const char* desc)
{
- dev->desc = desc;
+ device_set_desc_internal(dev, desc, FALSE);
+}
+
+void
+device_set_desc_copy(device_t dev, const char* desc)
+{
+ device_set_desc_internal(dev, desc, TRUE);
}
void *
@@ -784,6 +888,24 @@ device_unbusy(device_t dev)
}
}
+void
+device_quiet(device_t dev)
+{
+ dev->flags |= DF_QUIET;
+}
+
+void
+device_verbose(device_t dev)
+{
+ dev->flags &= ~DF_QUIET;
+}
+
+int
+device_is_quiet(device_t dev)
+{
+ return (dev->flags & DF_QUIET) != 0;
+}
+
int
device_is_enabled(device_t dev)
{
@@ -853,7 +975,8 @@ device_probe_and_attach(device_t dev)
if (dev->flags & DF_ENABLED) {
error = device_probe_child(bus, dev);
if (!error) {
- device_print_child(bus, dev);
+ if (!device_is_quiet(dev))
+ device_print_child(bus, dev);
error = DEVICE_ATTACH(dev);
if (!error)
dev->state = DS_ATTACHED;
@@ -884,7 +1007,9 @@ device_detach(device_t dev)
return 0;
if ((error = DEVICE_DETACH(dev)) != 0)
- return error;
+ return error;
+ if (dev->parent)
+ BUS_CHILD_DETACHED(dev->parent, dev);
if (!(dev->flags & DF_FIXEDCLASS))
devclass_delete_device(dev->devclass, dev);
@@ -903,6 +1028,124 @@ device_shutdown(device_t dev)
return DEVICE_SHUTDOWN(dev);
}
+#ifdef DEVICE_SYSCTLS
+
+/*
+ * Sysctl nodes for devices.
+ */
+
+SYSCTL_NODE(_hw, OID_AUTO, devices, CTLFLAG_RW, 0, "A list of all devices");
+
+static int
+sysctl_handle_children SYSCTL_HANDLER_ARGS
+{
+ device_t dev = arg1;
+ device_t child;
+ int first = 1, error = 0;
+
+ for (child = TAILQ_FIRST(&dev->children); child;
+ child = TAILQ_NEXT(child, link)) {
+ if (child->nameunit) {
+ if (!first) {
+ error = SYSCTL_OUT(req, ",", 1);
+ if (error) return error;
+ } else {
+ first = 0;
+ }
+ error = SYSCTL_OUT(req, child->nameunit, strlen(child->nameunit));
+ if (error) return error;
+ }
+ }
+
+ error = SYSCTL_OUT(req, "", 1);
+
+ return error;
+}
+
+static int
+sysctl_handle_state SYSCTL_HANDLER_ARGS
+{
+ device_t dev = arg1;
+
+ switch (dev->state) {
+ case DS_NOTPRESENT:
+ return SYSCTL_OUT(req, "notpresent", sizeof("notpresent"));
+ case DS_ALIVE:
+ return SYSCTL_OUT(req, "alive", sizeof("alive"));
+ case DS_ATTACHED:
+ return SYSCTL_OUT(req, "attached", sizeof("attached"));
+ case DS_BUSY:
+ return SYSCTL_OUT(req, "busy", sizeof("busy"));
+ }
+
+ return 0;
+}
+
+static void
+device_register_oids(device_t dev)
+{
+ struct sysctl_oid* oid;
+
+ oid = &dev->oid[0];
+ bzero(oid, sizeof(*oid));
+ oid->oid_parent = &sysctl__hw_devices_children;
+ oid->oid_number = OID_AUTO;
+ oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW;
+ oid->oid_arg1 = &dev->oidlist[0];
+ oid->oid_arg2 = 0;
+ oid->oid_name = dev->nameunit;
+ oid->oid_handler = 0;
+ oid->oid_fmt = "N";
+ SLIST_INIT(&dev->oidlist[0]);
+ sysctl_register_oid(oid);
+
+ oid = &dev->oid[1];
+ bzero(oid, sizeof(*oid));
+ oid->oid_parent = &dev->oidlist[0];
+ oid->oid_number = OID_AUTO;
+ oid->oid_kind = CTLTYPE_STRING | CTLFLAG_RD;
+ oid->oid_arg1 = dev->desc ? dev->desc : "";
+ oid->oid_arg2 = dev->desc ? strlen(dev->desc) : 0;
+ oid->oid_name = "desc";
+ oid->oid_handler = sysctl_handle_string;
+ oid->oid_fmt = "A";
+ sysctl_register_oid(oid);
+
+ oid = &dev->oid[2];
+ bzero(oid, sizeof(*oid));
+ oid->oid_parent = &dev->oidlist[0];
+ oid->oid_number = OID_AUTO;
+ oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
+ oid->oid_arg1 = dev;
+ oid->oid_arg2 = 0;
+ oid->oid_name = "children";
+ oid->oid_handler = sysctl_handle_children;
+ oid->oid_fmt = "A";
+ sysctl_register_oid(oid);
+
+ oid = &dev->oid[3];
+ bzero(oid, sizeof(*oid));
+ oid->oid_parent = &dev->oidlist[0];
+ oid->oid_number = OID_AUTO;
+ oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
+ oid->oid_arg1 = dev;
+ oid->oid_arg2 = 0;
+ oid->oid_name = "state";
+ oid->oid_handler = sysctl_handle_state;
+ oid->oid_fmt = "A";
+ sysctl_register_oid(oid);
+}
+
+static void
+device_unregister_oids(device_t dev)
+{
+ sysctl_unregister_oid(&dev->oid[0]);
+ sysctl_unregister_oid(&dev->oid[1]);
+ sysctl_unregister_oid(&dev->oid[2]);
+}
+
+#endif
+
/*
* Access functions for device resources.
*/
@@ -1236,6 +1479,23 @@ bus_release_resource(device_t dev, int type, int rid, struct resource *r)
type, rid, r));
}
+int
+bus_setup_intr(device_t dev, struct resource *r,
+ driver_intr_t handler, void *arg, void **cookiep)
+{
+ if (dev->parent == 0)
+ return (EINVAL);
+ return (BUS_SETUP_INTR(dev->parent, dev, r, handler, arg, cookiep));
+}
+
+int
+bus_teardown_intr(device_t dev, struct resource *r, void *cookie)
+{
+ if (dev->parent == 0)
+ return (EINVAL);
+ return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie));
+}
+
static void
root_print_child(device_t dev, device_t child)
{
@@ -1423,6 +1683,7 @@ print_device_short(device_t dev, int indent)
(dev->flags&DF_ENABLED? "enabled,":"disabled,"),
(dev->flags&DF_FIXEDCLASS? "fixed,":""),
(dev->flags&DF_WILDCARD? "wildcard,":""),
+ (dev->flags&DF_DESCMALLOCED? "descmalloced,":""),
(dev->ivars? "":"no "),
(dev->softc? "":"no "),
dev->busy));
diff --git a/sys/sys/bus.h b/sys/sys/bus.h
index 86316a8..3c7f9de 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.8 1999/01/16 17:44:08 dfr Exp $
+ * $Id: bus.h,v 1.9 1999/03/06 16:52:04 bde Exp $
*/
#ifndef _SYS_BUS_H_
@@ -74,7 +74,6 @@ struct driver {
driver_type_t type;
size_t softc; /* size of device softc struct */
void *priv; /* driver private data */
- TAILQ_ENTRY(driver) link; /* list of devices on bus */
device_ops_t ops; /* compiled method table */
};
@@ -136,6 +135,9 @@ int bus_deactivate_resource(device_t dev, int type, int rid,
struct resource *r);
int bus_release_resource(device_t dev, int type, int rid,
struct resource *r);
+int bus_setup_intr(device_t dev, struct resource *r,
+ driver_intr_t handler, void *arg, void **cookiep);
+int bus_teardown_intr(device_t dev, struct resource *r, void *cookie);
/*
* Access functions for device.
@@ -158,19 +160,24 @@ device_t device_get_parent(device_t dev);
int device_get_children(device_t dev, device_t **listp, int *countp);
void *device_get_ivars(device_t dev);
const char *device_get_name(device_t dev);
+const char *device_get_nameunit(device_t dev);
void *device_get_softc(device_t dev);
device_state_t device_get_state(device_t dev);
int device_get_unit(device_t dev);
-int device_is_enabled(device_t dev);
int device_is_alive(device_t dev); /* did probe succeed? */
+int device_is_enabled(device_t dev);
+int device_is_quiet(device_t dev);
void device_print_prettyname(device_t dev);
void device_printf(device_t dev, const char *, ...) __printflike(2, 3);
int device_probe_and_attach(device_t dev);
+void device_quiet(device_t dev);
void device_set_desc(device_t dev, const char* desc);
+void device_set_desc_copy(device_t dev, const char* desc);
int device_set_devclass(device_t dev, const char *classname);
int device_set_driver(device_t dev, driver_t *driver);
int device_shutdown(device_t dev);
void device_unbusy(device_t dev);
+void device_verbose(device_t dev);
/*
* Access functions for devclass.
diff --git a/sys/sys/bus_private.h b/sys/sys/bus_private.h
index 8dfa87c..8ac9944 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.3 1998/07/22 08:35:50 dfr Exp $
+ * $Id: bus_private.h,v 1.4 1998/11/14 21:58:41 wollman Exp $
*/
#ifndef _SYS_BUS_PRIVATE_H_
@@ -32,10 +32,19 @@
#include <sys/bus.h>
/*
+ * Used to attach drivers to devclasses.
+ */
+typedef struct driverlink *driverlink_t;
+struct driverlink {
+ driver_t *driver;
+ TAILQ_ENTRY(driverlink) link; /* list of drivers in devclass */
+};
+
+/*
* Forward declarations
*/
typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t;
-typedef TAILQ_HEAD(driver_list, driver) driver_list_t;
+typedef TAILQ_HEAD(driver_list, driverlink) driver_list_t;
typedef TAILQ_HEAD(device_list, device) device_list_t;
struct devclass {
@@ -109,13 +118,20 @@ struct device {
driver_t *driver;
devclass_t devclass; /* device class which we are in */
int unit;
- const char* desc; /* driver specific description */
+ char* nameunit; /* name+unit e.g. foodev0 */
+ char* desc; /* driver specific description */
int busy; /* count of calls to device_busy() */
device_state_t state;
int flags;
+#ifdef DEVICE_SYSCTLS
+ struct sysctl_oid oid[4];
+ struct sysctl_oid_list oidlist[1];
+#endif
#define DF_ENABLED 1 /* device should be probed/attached */
#define DF_FIXEDCLASS 2 /* devclass specified at create time */
#define DF_WILDCARD 4 /* unit was originally wildcard */
+#define DF_DESCMALLOCED 8 /* description was malloced */
+#define DF_QUIET 16 /* don't print verbose attach message */
void *ivars;
void *softc;
};
OpenPOWER on IntegriCloud