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>
next in thread | raw e-mail | index | archive | help
--=-=-= Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable 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=3D0x0c0500 card=3D0x24c21458 chip=3D0x24c3808= 6 rev=3D0x02 hdr=3D0x00 vendor =3D 'Intel Corporation' device =3D '82801DB/DBM (ICH4/M) SMBus Controller' class =3D serial bus subclass =3D SMBus - USB devices don't seem to report their location or pnpinfo. 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 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); --=-=-=--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzp8yiophgn.fsf>