Date: Fri, 27 Feb 2004 18:20:24 +0100 From: des@des.no (Dag-Erling =?iso-8859-1?q?Sm=F8rgrav?=) To: arch@freebsd.org Subject: 'sysctl dev', round two Message-ID: <xzp8yiophgn.fsf@dwp.des.no>
index | next in thread | raw e-mail
[-- Attachment #1 --]
New patch attached; it should be considerably cleaner than the
previous one. A couple of surprises, though:
- unattached devices still aren't picked up, which they should if
they have a device_t. For instance, I don't see a sysctl entry for
the following:
none0@pci0:31:3: class=0x0c0500 card=0x24c21458 chip=0x24c38086 rev=0x02 hdr=0x00
vendor = 'Intel Corporation'
device = '82801DB/DBM (ICH4/M) SMBus Controller'
class = serial bus
subclass = SMBus
- USB devices don't seem to report their location or pnpinfo.
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 27 Feb 2004 16:53:57 -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 {
@@ -185,6 +189,106 @@
#endif
/*
+ * dev sysctl tree
+ */
+
+enum {
+ DEVICE_SYSCTL_CLASS,
+ DEVICE_SYSCTL_DESC,
+ DEVICE_SYSCTL_DRIVER,
+ DEVICE_SYSCTL_LOCATION,
+ DEVICE_SYSCTL_PNPINFO,
+};
+
+static int
+device_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = (device_t)arg1;
+ const char *value;
+ char *buf;
+ int error;
+
+ buf = NULL;
+ switch (arg2) {
+ case DEVICE_SYSCTL_CLASS:
+ value = dev->devclass ? dev->devclass->name : NULL;
+ break;
+ case DEVICE_SYSCTL_DESC:
+ value = dev->desc;
+ break;
+ case DEVICE_SYSCTL_DRIVER:
+ value = dev->driver ? dev->driver->name : NULL;
+ break;
+ case DEVICE_SYSCTL_LOCATION:
+ value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
+ bus_child_location_str(dev, buf, 1024);
+ break;
+ case DEVICE_SYSCTL_PNPINFO:
+ value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO);
+ bus_child_pnpinfo_str(dev, buf, 1024);
+ 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
+device_sysctl_init(device_t dev)
+{
+ struct sysctl_oid_list *parent_node;
+
+ if (dev->parent) {
+ if (dev->parent->sysctl_tree == NULL)
+ device_sysctl_init(dev->parent);
+ parent_node = SYSCTL_CHILDREN(dev->parent->sysctl_tree);
+ } else {
+ parent_node = SYSCTL_STATIC_CHILDREN(_dev);
+ }
+ if (dev->sysctl_tree != NULL) {
+ sysctl_move_oid(dev->sysctl_tree, parent_node);
+ return;
+ }
+ sysctl_ctx_init(&dev->sysctl_ctx);
+ dev->sysctl_tree = SYSCTL_ADD_NODE(&dev->sysctl_ctx, parent_node,
+ OID_AUTO, dev->nameunit, 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");
+ 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");
+ SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
+ OID_AUTO, "%location", CTLFLAG_RD,
+ dev, DEVICE_SYSCTL_LOCATION, device_sysctl_handler, "A",
+ "device location relative to parent");
+ SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree),
+ OID_AUTO, "%pnpinfo", CTLFLAG_RD,
+ dev, DEVICE_SYSCTL_PNPINFO, device_sysctl_handler, "A",
+ "device identification");
+}
+
+static void
+device_sysctl_fini(device_t dev)
+{
+ if (dev->sysctl_tree == NULL)
+ return;
+ sysctl_ctx_free(&dev->sysctl_ctx);
+ dev->sysctl_tree = NULL;
+}
+
+/*
* /dev/devctl implementation
*/
@@ -886,6 +990,7 @@
dc->devices[dev->unit] = dev;
dev->devclass = dc;
snprintf(dev->nameunit, buflen, "%s%d", dc->name, dev->unit);
+ device_sysctl_init(dev);
return (0);
}
@@ -900,6 +1005,7 @@
if (dev->devclass != dc || dc->devices[dev->unit] != dev)
panic("devclass_delete_device: inconsistent device class");
+ device_sysctl_fini(dev);
dc->devices[dev->unit] = NULL;
if (dev->flags & DF_WILDCARD)
dev->unit = -1;
@@ -956,9 +1062,7 @@
}
dev->ivars = NULL;
dev->softc = NULL;
-
dev->state = DS_NOTPRESENT;
-
TAILQ_INSERT_TAIL(&bus_data_devices, dev, devlink);
bus_data_generation_update();
@@ -1043,6 +1147,7 @@
TAILQ_REMOVE(&dev->children, child, link);
TAILQ_REMOVE(&bus_data_devices, child, devlink);
device_set_desc(child, NULL);
+ device_sysctl_fini(dev);
kobj_delete((kobj_t) child, M_BUS);
bus_data_generation_update();
@@ -1254,6 +1359,18 @@
device_get_flags(device_t dev)
{
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
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 27 Feb 2004 15:44:30 -0000
@@ -335,6 +335,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);
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzp8yiophgn.fsf>
