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
--=-=-= Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable 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 --=20 Dag-Erling Sm=F8rgrav - des@des.no --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=dev.diff 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 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=ndis.diff 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>