Date: Thu, 26 Feb 2004 19:06:24 +0100 From: des@des.no (Dag-Erling =?iso-8859-1?q?Sm=F8rgrav?=) To: arch@freebsd.org Subject: per-device sysctls Message-ID: <xzpk729lnq7.fsf@dwp.des.no>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
The first of the attached patches creates a sysctl context and node
for every device in the system named for its nameunit. Each device's
sysctl node is a child of the parent device's sysctl node, so the
resulting sysctl tree resembles the "show devices by attachment" mode
of Windows's device manager. Standard entries in each device's tree
include %class, %desc and %driver (device class, device description
and driver name). I also plan to add entries for device IDs, irq /
drq lines etc., but this will require additional bus-specific code and
is not yet implemented.
Note that root0 is not created through the usual means and therefore
does not get its own sysctl node; its children (nexus0 on i386) are
placed directly in dev. I haven't yet decided whether this is a
feature or a bug.
The second patch modifies the NDISulator to use the per-device context
and tree rather than create its own. There are several other drivers
that do this; I chose the NDISulator because I can actually test it.
DES
--
Dag-Erling Smørgrav - des@des.no
[-- Attachment #2 --]
Index: sys/kern/subr_bus.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/subr_bus.c,v
retrieving revision 1.140
diff -u -r1.140 subr_bus.c
--- sys/kern/subr_bus.c 24 Feb 2004 19:31:30 -0000 1.140
+++ sys/kern/subr_bus.c 26 Feb 2004 16:11:13 -0000
@@ -56,6 +56,7 @@
#include <vm/uma.h>
SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
+SYSCTL_NODE(, OID_AUTO, dev, CTLFLAG_RW, NULL, NULL);
/*
* Used to attach drivers to devclasses.
@@ -123,6 +124,9 @@
u_char pad;
void *ivars;
void *softc;
+
+ struct sysctl_ctx_list sysctl_ctx;
+ struct sysctl_oid *sysctl_tree;
};
struct device_op_desc {
@@ -252,6 +256,8 @@
static dev_t devctl_dev;
+static struct sysctl_ctx_list device_sysctl_ctx;
+
static void
devinit(void)
{
@@ -260,6 +266,7 @@
mtx_init(&devsoftc.mtx, "dev mtx", "devd", MTX_DEF);
cv_init(&devsoftc.cv, "dev cv");
TAILQ_INIT(&devsoftc.devq);
+ sysctl_ctx_init(&device_sysctl_ctx);
}
static int
@@ -381,6 +388,8 @@
struct dev_event_info *n1 = NULL;
struct proc *p;
+ if (*data != '?')
+ printf("devctl: %s", data);
n1 = malloc(sizeof(*n1), M_BUS, M_NOWAIT);
if (n1 == NULL)
return;
@@ -1256,6 +1265,18 @@
return (dev->devflags);
}
+struct sysctl_ctx_list *
+device_get_sysctl_ctx(device_t dev)
+{
+ return (&dev->sysctl_ctx);
+}
+
+struct sysctl_oid *
+device_get_sysctl_tree(device_t dev)
+{
+ return (dev->sysctl_tree);
+}
+
int
device_print_prettyname(device_t dev)
{
@@ -1509,7 +1530,7 @@
if (!error) {
if (!device_is_quiet(dev))
device_print_child(bus, dev);
- error = DEVICE_ATTACH(dev);
+ error = device_attach(dev);
if (!error) {
dev->state = DS_ATTACHED;
devadded(dev);
@@ -1539,6 +1560,71 @@
return (error);
}
+enum {
+ DEVICE_SYSCTL_CLASS,
+ DEVICE_SYSCTL_DESC,
+ DEVICE_SYSCTL_DRIVER,
+};
+
+static int
+device_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ const char *value;
+ size_t len;
+
+ switch (arg2) {
+ case DEVICE_SYSCTL_CLASS:
+ value = dev->devclass->name;
+ break;
+ case DEVICE_SYSCTL_DESC:
+ value = dev->desc;
+ break;
+ case DEVICE_SYSCTL_DRIVER:
+ value = dev->driver->name;
+ break;
+ default:
+ return (EINVAL);
+ }
+ if (value == NULL)
+ return (ENODEV);
+ len = strlen(value);
+ return (SYSCTL_OUT(req, value, strlen(value)));
+}
+
+int
+device_attach(device_t dev)
+{
+ struct sysctl_oid_list *parent_node;
+ int error;
+
+ sysctl_ctx_init(&dev->sysctl_ctx);
+ if (dev->parent && dev->parent->sysctl_tree)
+ parent_node = SYSCTL_CHILDREN(dev->parent->sysctl_tree);
+ else
+ parent_node = SYSCTL_STATIC_CHILDREN(_dev);
+ dev->sysctl_tree = SYSCTL_ADD_NODE(&dev->sysctl_ctx, parent_node,
+ OID_AUTO, dev->nameunit, CTLFLAG_RD, 0, "");
+ if ((error = DEVICE_ATTACH(dev)) != 0) {
+ sysctl_ctx_free(&dev->sysctl_ctx);
+ dev->sysctl_tree = NULL;
+ return (error);
+ }
+ 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");
+ SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
+ OID_AUTO, "%driver", CTLFLAG_RD,
+ dev, DEVICE_SYSCTL_DRIVER, device_sysctl_handler, "A",
+ "device driver name");
+ return (0);
+}
+
int
device_detach(device_t dev)
{
@@ -1552,6 +1638,10 @@
if ((error = DEVICE_DETACH(dev)) != 0)
return (error);
+ if (dev->sysctl_tree != NULL) {
+ sysctl_ctx_free(&dev->sysctl_ctx);
+ dev->sysctl_tree = NULL;
+ }
devremoved(dev);
device_printf(dev, "detached\n");
if (dev->parent)
Index: sys/sys/bus.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/bus.h,v
retrieving revision 1.57
diff -u -r1.57 bus.h
--- sys/sys/bus.h 24 Oct 2003 22:41:54 -0000 1.57
+++ sys/sys/bus.h 26 Feb 2004 15:51:43 -0000
@@ -317,6 +317,7 @@
const char *name, int unit);
void device_busy(device_t dev);
int device_delete_child(device_t dev, device_t child);
+int device_attach(device_t dev);
int device_detach(device_t dev);
void device_disable(device_t dev);
void device_enable(device_t dev);
@@ -335,6 +336,8 @@
void *device_get_softc(device_t dev);
device_state_t device_get_state(device_t dev);
int device_get_unit(device_t dev);
+struct sysctl_ctx_list *device_get_sysctl_ctx(device_t dev);
+struct sysctl_oid *device_get_sysctl_tree(device_t dev);
int device_is_alive(device_t dev); /* did probe succeed? */
int device_is_attached(device_t dev); /* did attach succeed? */
int device_is_enabled(device_t dev);
Index: sys/sys/sysctl.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/sysctl.h,v
retrieving revision 1.124
diff -u -r1.124 sysctl.h
--- sys/sys/sysctl.h 26 Feb 2004 00:27:03 -0000 1.124
+++ sys/sys/sysctl.h 26 Feb 2004 13:30:25 -0000
@@ -52,7 +52,7 @@
* respective subsystem header files.
*/
-#define CTL_MAXNAME 12 /* largest number of components supported */
+#define CTL_MAXNAME 24 /* largest number of components supported */
/*
* Each subsystem defined by sysctl defines a list of variables
[-- Attachment #3 --]
Index: sys/compat/ndis/kern_ndis.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/ndis/kern_ndis.c,v
retrieving revision 1.39
diff -u -r1.39 kern_ndis.c
--- sys/compat/ndis/kern_ndis.c 14 Feb 2004 20:57:32 -0000 1.39
+++ sys/compat/ndis/kern_ndis.c 26 Feb 2004 16:05:07 -0000
@@ -585,6 +585,8 @@
ndis_create_sysctls(arg)
void *arg;
{
+ struct sysctl_ctx_list *sysctl_ctx;
+ struct sysctl_oid *sysctl_tree;
struct ndis_softc *sc;
ndis_cfg *vals;
char buf[256];
@@ -597,12 +599,8 @@
TAILQ_INIT(&sc->ndis_cfglist_head);
- /* Create the sysctl tree. */
-
- sc->ndis_tree = SYSCTL_ADD_NODE(&sc->ndis_ctx,
- SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
- device_get_nameunit(sc->ndis_dev), CTLFLAG_RD, 0,
- device_get_desc(sc->ndis_dev));
+ sysctl_ctx = device_get_sysctl_ctx(sc->ndis_dev);
+ sysctl_tree = device_get_sysctl_tree(sc->ndis_dev);
/* Add the driver-specific registry keys. */
@@ -614,8 +612,8 @@
vals++;
continue;
}
- SYSCTL_ADD_STRING(&sc->ndis_ctx,
- SYSCTL_CHILDREN(sc->ndis_tree),
+ SYSCTL_ADD_STRING(sysctl_ctx,
+ SYSCTL_CHILDREN(sysctl_tree),
OID_AUTO, vals->nc_cfgkey,
CTLFLAG_RW, vals->nc_val,
sizeof(vals->nc_val),
@@ -684,7 +682,8 @@
TAILQ_INSERT_TAIL(&sc->ndis_cfglist_head, cfg, link);
- SYSCTL_ADD_STRING(&sc->ndis_ctx, SYSCTL_CHILDREN(sc->ndis_tree),
+ SYSCTL_ADD_STRING(device_get_sysctl_ctx(sc->ndis_dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(sc->ndis_dev)),
OID_AUTO, cfg->ndis_cfg.nc_cfgkey, flag,
cfg->ndis_cfg.nc_val, sizeof(cfg->ndis_cfg.nc_val),
cfg->ndis_cfg.nc_cfgdesc);
Index: sys/compat/ndis/subr_ndis.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/ndis/subr_ndis.c,v
retrieving revision 1.48
diff -u -r1.48 subr_ndis.c
--- sys/compat/ndis/subr_ndis.c 16 Feb 2004 02:50:03 -0000 1.48
+++ sys/compat/ndis/subr_ndis.c 26 Feb 2004 15:49:19 -0000
@@ -582,7 +582,7 @@
* See if registry key is already in a list of known keys
* included with the driver.
*/
- TAILQ_FOREACH(e, &sc->ndis_ctx, link) {
+ TAILQ_FOREACH(e, device_get_sysctl_ctx(sc->ndis_dev), link) {
oidp = e->entry;
if (strcmp(oidp->oid_name, keystr) == 0) {
if (strcmp((char *)oidp->oid_arg1, "UNSET") == 0) {
@@ -678,7 +678,7 @@
/* See if the key already exists. */
- TAILQ_FOREACH(e, &sc->ndis_ctx, link) {
+ TAILQ_FOREACH(e, device_get_sysctl_ctx(sc->ndis_dev), link) {
oidp = e->entry;
if (strcmp(oidp->oid_name, keystr) == 0) {
/* Found it, set the value. */
Index: sys/dev/if_ndis/if_ndis.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/if_ndis/if_ndis.c,v
retrieving revision 1.42
diff -u -r1.42 if_ndis.c
--- sys/dev/if_ndis/if_ndis.c 11 Feb 2004 21:53:40 -0000 1.42
+++ sys/dev/if_ndis/if_ndis.c 26 Feb 2004 15:44:52 -0000
@@ -43,7 +43,6 @@
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/queue.h>
-#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -586,8 +585,6 @@
else
sc->ndis_devidx = devidx;
- sysctl_ctx_init(&sc->ndis_ctx);
-
/* Create sysctl registry nodes */
ndis_create_sysctls(sc);
@@ -948,8 +945,6 @@
ndis_unload_driver((void *)ifp);
bus_dma_tag_destroy(sc->ndis_parent_tag);
-
- sysctl_ctx_free(&sc->ndis_ctx);
return(0);
}
Index: sys/dev/if_ndis/if_ndisvar.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/if_ndis/if_ndisvar.h,v
retrieving revision 1.10
diff -u -r1.10 if_ndisvar.h
--- sys/dev/if_ndis/if_ndisvar.h 27 Jan 2004 09:08:12 -0000 1.10
+++ sys/dev/if_ndis/if_ndisvar.h 26 Feb 2004 15:44:46 -0000
@@ -104,8 +104,6 @@
int ndis_if_flags;
int ndis_skip;
- struct sysctl_ctx_list ndis_ctx;
- struct sysctl_oid *ndis_tree;
int ndis_devidx;
interface_type ndis_iftype;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzpk729lnq7.fsf>
