[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree
zrouter-src-freebsd at zrouter.org
zrouter-src-freebsd at zrouter.org
Wed Feb 1 10:57:08 UTC 2012
details: http://zrouter.org/hg/FreeBSD/head//rev/9f71f5dba02d
changeset: 328:9f71f5dba02d
user: ray at terran.dlink.ua
date: Wed Feb 01 12:36:49 2012 +0200
description:
Add devctl utility and kernel code
diffstat:
head/sbin/devctl/Makefile | 7 ++
head/sbin/devctl/devctl.8 | 127 ++++++++++++++++++++++++++++++++++++++++++++++
head/sbin/devctl/devctl.c | 120 +++++++++++++++++++++++++++++++++++++++++++
head/sys/conf/options | 1 +
head/sys/kern/subr_bus.c | 117 ++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 371 insertions(+), 1 deletions(-)
diffs (419 lines):
diff -r cd6b4b1a93f5 -r 9f71f5dba02d head/sbin/devctl/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sbin/devctl/Makefile Wed Feb 01 12:36:49 2012 +0200
@@ -0,0 +1,7 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+# $FreeBSD$
+
+PROG= devctl
+CFLAGS += -I${.CURDIR}/../../sys/ -DDEVCTL_ATTACH_ENABLED
+
+.include <bsd.prog.mk>
diff -r cd6b4b1a93f5 -r 9f71f5dba02d head/sbin/devctl/devctl.8
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sbin/devctl/devctl.8 Wed Feb 01 12:36:49 2012 +0200
@@ -0,0 +1,127 @@
+.\" Copyright (c) 2012
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)devctl.8 8.1 (Berkeley) 6/5/93
+.\" $FreeBSD$
+.\"
+.Dd January 31, 2012
+.Dt DEVCTL 8
+.Os
+.Sh NAME
+.Nm devctl
+.Nd "attach/detach devices that can not be auto enumerated"
+.Sh SYNOPSIS
+.Nm devctl
+.Ar attach | hinted
+.Ar parentdevclass
+.Ar parentunit
+.Ar devclass
+.Op Ar unit
+.Nm devctl
+.Ar detach
+.Ar pdevclass
+.Ar punit
+.Ar devclass
+.Ar unit
+.Sh DESCRIPTION
+The
+.Nm devctl
+utilities are used to attach or detach devices that can not be auto enumerated.
+.Bl -tag -width indent
+.It Ar attach
+to call
+.Xr device_add_child 9
+and then
+.Xr device_probe_and_attach 9
+.It Ar hinted
+to attach device with BUS_HINTED_CHILD macro which call bus_hinted_child device method
+.It Ar detach
+to remove device from parent device child list by call to
+.Xr device_delete_child 9
+.It Ar pdevclass
+name of device which is parent to new device or device which will be removed
+.It Ar punit
+unit of parent device
+.It Ar devclass
+devclass of new device or device which will be removed
+.It Ar unit
+unit of new device, optional for
+.Ar attach
+and
+.Ar hinted
+, required for
+.Ar detach
+.
+.El
+.Pp
+To enable this facility in kernel put options DEVCTL_ATTACH_ENABLED into kernel config file.
+Kernel will create device file with name
+.Xr devctl2 4
+.Sh EXAMPLES
+.Dl devctl hinted spibus 0 mx25l 0
+.Pp
+will try to attach device with class mx25l and unit 0 to bus spibus0.
+.Pp
+.Dl devctl hinted spibus 0 mx25l
+.Pp
+same, but unit number will be assigned automatically.
+.Pp
+.Dl devctl detach spibus 0 mx25l 0
+.Pp
+will delete device mx25l0 from child list of bus spibus0.
+.Sh DIAGNOSTICS
+These utilities may fail with following error messages:
+.Bl -tag -width indent
+.It Device not configured.
+For
+.Ar attach
+or
+.Ar hinted
+methods if parent device not found or if device class of new device not found.
+For
+.Ar devclass
+method if parent or child device not found.
+.It Xr device_probe_and_attach 9 error codes.
+if
+.Ar attach
+method fail.
+.It Xr bus_generic_attach 9 error codes.
+if
+.Ar hinted
+method fail.
+.It Xr device_delete_child 9 error codes.
+if
+.Ar detach
+method fail.
+.El
+.Sh SEE ALSO
+.Xr devctl2 4 ,
+.Sh HISTORY
+The
+.Nm devctl
+utility appeared in
+.Fx 10.0 .
diff -r cd6b4b1a93f5 -r 9f71f5dba02d head/sbin/devctl/devctl.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/head/sbin/devctl/devctl.c Wed Feb 01 12:36:49 2012 +0200
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2012 by Rybalko Aleksandr.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/bus.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+#include <string.h>
+#include <err.h>
+
+#include <stdlib.h>
+#include <limits.h>
+
+#define DEVCTL "/dev/devctl2"
+#define MODE_ATTACH 1
+#define MODE_HINTED 2
+#define MODE_DETACH 3
+
+static void usage(void);
+
+static void
+usage()
+{
+ printf("devctl attach bus_name bus_unit dev_name [dev_unit]\n");
+ printf("devctl hinted bus_name bus_unit dev_name [dev_unit]\n");
+ printf("devctl detach bus_name bus_unit dev_name dev_unit\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ struct devctl_attach_args args;
+ int fd, mode, error;
+
+ error = 0;
+ if (argc < 5) {
+ usage();
+ return (1);
+ }
+
+ if (strcmp(argv[1], "attach") == 0)
+ mode = MODE_ATTACH;
+ if (strcmp(argv[1], "hinted") == 0)
+ mode = MODE_HINTED;
+ if (strcmp(argv[1], "detach") == 0)
+ mode = MODE_DETACH;
+ if ((mode != MODE_ATTACH) &&
+ (mode != MODE_HINTED) &&
+ (mode != MODE_DETACH))
+ err(1, "can only attach/hinted/detach device");
+
+ if ((mode == MODE_DETACH) && argc < 6)
+ err(1, "explicit device unit number required for detach");
+
+ args.bus_name = argv[2];
+ args.bus_unit = strtoul(argv[3], 0, 0);
+ args.dev_name = argv[4];
+ if (argc == 6) {
+ args.dev_unit = strtoul(argv[5], 0, 0);
+ } else {
+ args.dev_unit = -1;
+ }
+
+ fd = open(DEVCTL, O_RDONLY);
+ if (fd == -1)
+ err(1, "can't open " DEVCTL " file");
+
+
+ switch (mode) {
+ case MODE_ATTACH:
+ error = ioctl(fd, DEVCTLADEV, &args);
+ break;
+ case MODE_HINTED:
+ error = ioctl(fd, DEVCTLAHDEV, &args);
+ break;
+ case MODE_DETACH:
+ error = ioctl(fd, DEVCTLDDEV, &args);
+ break;
+ }
+
+ if (error == -1) {
+ close(fd);
+ err(1, "ioctl failed");
+ }
+
+ close(fd);
+
+ return (0);
+}
+
diff -r cd6b4b1a93f5 -r 9f71f5dba02d head/sys/conf/options
--- a/head/sys/conf/options Wed Feb 01 12:34:54 2012 +0200
+++ b/head/sys/conf/options Wed Feb 01 12:36:49 2012 +0200
@@ -647,6 +647,7 @@
# options for bus/device framework
BUS_DEBUG opt_bus.h
+DEVCTL_ATTACH_ENABLED opt_bus.h
# options for USB support
USB_DEBUG opt_usb.h
diff -r cd6b4b1a93f5 -r 9f71f5dba02d head/sys/kern/subr_bus.c
--- a/head/sys/kern/subr_bus.c Wed Feb 01 12:34:54 2012 +0200
+++ b/head/sys/kern/subr_bus.c Wed Feb 01 12:36:49 2012 +0200
@@ -412,6 +412,116 @@
TAILQ_INIT(&devsoftc.devq);
}
+#ifdef DEVCTL_ATTACH_ENABLED
+
+static d_open_t devctl2_open;
+static d_close_t devctl2_close;
+static d_ioctl_t devctl2_ioctl;
+
+static struct cdevsw devctl2_cdevsw = {
+ .d_version = D_VERSION,
+ .d_flags = D_NEEDGIANT,
+ .d_open = devctl2_open,
+ .d_close = devctl2_close,
+ .d_ioctl = devctl2_ioctl,
+ .d_name = "devctl2",
+};
+
+static struct cdev *devctl2_dev;
+
+static void
+devctl2_init(void)
+{
+ devctl2_dev = make_dev_credf(MAKEDEV_ETERNAL, &devctl2_cdevsw, 0, NULL,
+ UID_ROOT, GID_WHEEL, 0600, "devctl2");
+}
+
+#define FIND_DEV(_n, _u) \
+ devclass_get_device(devclass_find(_n), (_u))
+
+static int
+devctl2_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
+{
+ return (0);
+}
+
+static int
+devctl2_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
+{
+ return (0);
+}
+
+static int
+devctl2_attach_device(struct devctl_attach_args *arg)
+{
+ device_t bus, child;
+
+ /* TODO: check args */
+ bus = FIND_DEV(arg->bus_name, arg->bus_unit);
+ if (!bus)
+ return (ENXIO);
+
+ child = device_add_child(bus, arg->dev_name, arg->dev_unit);
+ if (!child)
+ return (ENXIO);
+
+ return (device_probe_and_attach(child));
+}
+
+static int
+devctl2_attach_hinted_device(struct devctl_attach_args *arg)
+{
+ device_t bus;
+
+ /* TODO: check args */
+ bus = FIND_DEV(arg->bus_name, arg->bus_unit);
+ if (!bus)
+ return (ENXIO);
+
+ BUS_HINTED_CHILD(bus, arg->dev_name, arg->dev_unit);
+
+ return (bus_generic_attach(bus));
+}
+
+static int
+devctl2_detach_device(struct devctl_attach_args *arg)
+{
+ device_t bus, child;
+
+ /* TODO: check args */
+ bus = FIND_DEV(arg->bus_name, arg->bus_unit);
+ if (!bus)
+ return (ENXIO);
+
+ child = FIND_DEV(arg->dev_name, arg->dev_unit);
+ if (!child)
+ return (ENXIO);
+
+ return (device_delete_child(bus, child));
+}
+
+static int
+devctl2_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
+ struct thread *td)
+{
+
+ switch (cmd) {
+ case DEVCTLADEV:
+ return (devctl2_attach_device(
+ (struct devctl_attach_args *)data));
+ case DEVCTLAHDEV:
+ return (devctl2_attach_hinted_device(
+ (struct devctl_attach_args *)data));
+ case DEVCTLDDEV:
+ return (devctl2_detach_device(
+ (struct devctl_attach_args *)data));
+ default:
+ break;
+ }
+ return (ENOTTY);
+}
+#endif
+
static int
devopen(struct cdev *dev, int oflags, int devtype, struct thread *td)
{
@@ -475,8 +585,10 @@
}
static int
-devioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
+devioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
+ struct thread *td)
{
+
switch (cmd) {
case FIONBIO:
@@ -4402,6 +4514,9 @@
root_bus->state = DS_ATTACHED;
root_devclass = devclass_find_internal("root", NULL, FALSE);
devinit();
+#ifdef DEVCTL_ATTACH_ENABLED
+ devctl2_init();
+#endif
return (0);
case MOD_SHUTDOWN:
More information about the Zrouter-src-freebsd
mailing list