summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_bus.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2004-06-04 10:23:00 +0000
committerdes <des@FreeBSD.org>2004-06-04 10:23:00 +0000
commit7fec1d493133d2b669b572d3dca639704968dd51 (patch)
tree399940cb8da5617d996f6b5712b08fa15438a026 /sys/kern/subr_bus.c
parent87b856667a621219e131b677f5a09e0938f1e5f8 (diff)
downloadFreeBSD-src-7fec1d493133d2b669b572d3dca639704968dd51.zip
FreeBSD-src-7fec1d493133d2b669b572d3dca639704968dd51.tar.gz
Add a devclass level to the dev sysctl tree, in order to support per-
class variables in addition to per-device variables. In plain English, this means that dev.foo0.bar is now called dev.foo.0.bar, and it is possible to to have dev.foo.bar as well.
Diffstat (limited to 'sys/kern/subr_bus.c')
-rw-r--r--sys/kern/subr_bus.c74
1 files changed, 64 insertions, 10 deletions
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 3ff1f5f..e997897 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -81,6 +81,9 @@ struct devclass {
char *name;
device_t *devices; /* array of devices indexed by unit */
int maxunit; /* size of devices array */
+
+ struct sysctl_ctx_list sysctl_ctx;
+ struct sysctl_oid *sysctl_tree;
};
/*
@@ -193,7 +196,50 @@ void print_devclass_list(void);
*/
enum {
- DEVICE_SYSCTL_CLASS,
+ DEVCLASS_SYSCTL_PARENT,
+};
+
+static int
+devclass_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+ devclass_t dc = (devclass_t)arg1;
+ const char *value;
+ char *buf;
+ int error;
+
+ buf = NULL;
+ switch (arg2) {
+ case DEVCLASS_SYSCTL_PARENT:
+ value = dc->parent ? dc->parent->name : NULL;
+ break;
+ default:
+ return (EINVAL);
+ }
+ if (value == NULL)
+ value = "?";
+ error = SYSCTL_OUT(req, value, strlen(value));
+ if (buf != NULL)
+ free(buf, M_BUS);
+ return (error);
+}
+
+static void
+devclass_sysctl_init(devclass_t dc)
+{
+
+ if (dc->sysctl_tree != NULL)
+ return;
+ sysctl_ctx_init(&dc->sysctl_ctx);
+ dc->sysctl_tree = SYSCTL_ADD_NODE(&dc->sysctl_ctx,
+ SYSCTL_STATIC_CHILDREN(_dev), OID_AUTO, dc->name,
+ CTLFLAG_RD, 0, "");
+ SYSCTL_ADD_PROC(&dc->sysctl_ctx, SYSCTL_CHILDREN(dc->sysctl_tree),
+ OID_AUTO, "%parent", CTLFLAG_RD,
+ dc, DEVCLASS_SYSCTL_PARENT, devclass_sysctl_handler, "A",
+ "parent class");
+}
+
+enum {
DEVICE_SYSCTL_DESC,
DEVICE_SYSCTL_DRIVER,
DEVICE_SYSCTL_LOCATION,
@@ -211,9 +257,6 @@ device_sysctl_handler(SYSCTL_HANDLER_ARGS)
buf = NULL;
switch (arg2) {
- case DEVICE_SYSCTL_CLASS:
- value = dev->devclass ? dev->devclass->name : NULL;
- break;
case DEVICE_SYSCTL_DESC:
value = dev->desc;
break;
@@ -245,18 +288,17 @@ device_sysctl_handler(SYSCTL_HANDLER_ARGS)
static void
device_sysctl_init(device_t dev)
{
+ devclass_t dc = dev->devclass;
if (dev->sysctl_tree != NULL)
return;
+ devclass_sysctl_init(dc);
sysctl_ctx_init(&dev->sysctl_ctx);
dev->sysctl_tree = SYSCTL_ADD_NODE(&dev->sysctl_ctx,
- SYSCTL_STATIC_CHILDREN(_dev), OID_AUTO, dev->nameunit,
+ SYSCTL_CHILDREN(dc->sysctl_tree), OID_AUTO,
+ dev->nameunit + strlen(dc->name),
CTLFLAG_RD, 0, "");
SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
- OID_AUTO, "%class", CTLFLAG_RD,
- dev, DEVICE_SYSCTL_CLASS, device_sysctl_handler, "A",
- "device class name");
- SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
OID_AUTO, "%desc", CTLFLAG_RD,
dev, DEVICE_SYSCTL_DESC, device_sysctl_handler, "A",
"device description");
@@ -275,7 +317,7 @@ device_sysctl_init(device_t dev)
SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
OID_AUTO, "%parent", CTLFLAG_RD,
dev, DEVICE_SYSCTL_PARENT, device_sysctl_handler, "A",
- "device parent");
+ "parent device");
}
static void
@@ -915,6 +957,18 @@ devclass_get_parent(devclass_t dc)
return (dc->parent);
}
+struct sysctl_ctx_list *
+devclass_get_sysctl_ctx(devclass_t dc)
+{
+ return (&dc->sysctl_ctx);
+}
+
+struct sysctl_oid *
+devclass_get_sysctl_tree(devclass_t dc)
+{
+ return (dc->sysctl_tree);
+}
+
static int
devclass_alloc_unit(devclass_t dc, int *unitp)
{
OpenPOWER on IntegriCloud