From owner-freebsd-arch@FreeBSD.ORG Fri Feb 27 09:20:37 2004 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 08DA916A4CE for ; Fri, 27 Feb 2004 09:20:37 -0800 (PST) Received: from smtp.des.no (flood.des.no [217.116.83.31]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3025543D1D for ; Fri, 27 Feb 2004 09:20:36 -0800 (PST) (envelope-from des@des.no) Received: by smtp.des.no (Pony Express, from userid 666) id 1CFE15309; Fri, 27 Feb 2004 18:20:35 +0100 (CET) Received: from dwp.des.no (des.no [80.203.228.37]) by smtp.des.no (Pony Express) with ESMTP id BBD755308 for ; Fri, 27 Feb 2004 18:20:24 +0100 (CET) Received: by dwp.des.no (Postfix, from userid 2602) id 42D8033C71; Fri, 27 Feb 2004 18:20:24 +0100 (CET) To: arch@freebsd.org From: des@des.no (Dag-Erling =?iso-8859-1?q?Sm=F8rgrav?=) Date: Fri, 27 Feb 2004 18:20:24 +0100 Message-ID: User-Agent: Gnus/5.090024 (Oort Gnus v0.24) Emacs/21.3 (berkeley-unix) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Checker-Version: SpamAssassin 2.63 (2004-01-11) on flood.des.no X-Spam-Level: X-Spam-Status: No, hits=0.0 required=5.0 tests=AWL autolearn=no version=2.63 Subject: 'sysctl dev', round two X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Feb 2004 17:20:37 -0000 --=-=-= 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 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); --=-=-=--