Index: sys/sys/devio.h =================================================================== RCS file: sys/sys/devio.h diff -N sys/sys/devio.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/sys/devio.h 27 Mar 2008 05:39:06 -0000 @@ -0,0 +1,19 @@ +#ifndef _SYS_DEVIO_H +#define _SYS_DEVIO_H + +#ifndef _KERNEL +#include +#endif +#include + +#define MAXDEVNAME 32 +struct device_ioctl +{ + char dio_devclass[MAXDEVNAME]; + int dio_unit; +}; + +#define DEVIOC_SUSPEND _IOW('d', 1, struct device_ioctl) +#define DEVIOC_RESUME _IOW('d', 2, struct device_ioctl) + +#endif /* _SYS_DEVIO_H */ Index: sys/kern/subr_bus.c =================================================================== RCS file: /cache/ncvs/src/sys/kern/subr_bus.c,v retrieving revision 1.207 diff -u -r1.207 subr_bus.c --- sys/kern/subr_bus.c 20 Mar 2008 21:24:32 -0000 1.207 +++ sys/kern/subr_bus.c 27 Mar 2008 06:26:12 -0000 @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -403,8 +404,10 @@ static int devopen(struct cdev *dev, int oflags, int devtype, d_thread_t *td) { +#if 0 if (devsoftc.inuse) return (EBUSY); +#endif /* move to init */ devsoftc.inuse = 1; devsoftc.nonblock = 0; @@ -479,6 +482,26 @@ devsoftc.async_proc = NULL; return (0); + case DEVIOC_SUSPEND: + case DEVIOC_RESUME: + { + devclass_t dc; + device_t dev; + struct device_ioctl *dio = (struct device_ioctl *)data; + int err; + + dc = devclass_find(dio->dio_devclass); + if (dc == NULL) + return (ENXIO); + dev = devclass_get_device(dc, dio->dio_unit); + if (dev == NULL) + return (ENXIO); + if (cmd == DEVIOC_SUSPEND) + err = DEVICE_SUSPEND(dev); + else + err = DEVICE_RESUME(dev); + return (err); + } /* (un)Support for other fcntl() calls. */ case FIOCLEX: case FIONCLEX: Index: usr.bin/devctl/Makefile =================================================================== RCS file: usr.bin/devctl/Makefile diff -N usr.bin/devctl/Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/devctl/Makefile 27 Mar 2008 06:52:22 -0000 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +PROG= devctl + +.include Index: usr.bin/devctl/devctl.1 =================================================================== RCS file: usr.bin/devctl/devctl.1 diff -N usr.bin/devctl/devctl.1 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/devctl/devctl.1 27 Mar 2008 06:55:09 -0000 @@ -0,0 +1,40 @@ +.\" +.\" Copyright (c) 2008 M. Warner Losh. +.\" 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 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 AUTHOR 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. +.\" +.\" $FreeBSD: src/sbin/devd/devd.8,v 1.17 2006/09/17 22:49:26 ru Exp $ +.\" +.Dd March 27, 2008 +.Dt devctl 1 +.Os +.Sh NAME +.Nm devctl +.Nd "device state change utility" +.Sh SYNOPSIS +.Nm +.Op Fl rs +.Sh DESCRIPTION +The +.Nm +utility suspends and resumes devices. Index: usr.bin/devctl/devctl.c =================================================================== RCS file: usr.bin/devctl/devctl.c diff -N usr.bin/devctl/devctl.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ usr.bin/devctl/devctl.c 27 Mar 2008 06:01:11 -0000 @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include + +void +usage() +{ + fprintf(stderr, "devctl [-r] [-s] devname devunit\n"); + exit(1); +} + +int +main(int argc, char **argv) +{ + int ch, fd; + int rflag = 0; + int sflag = 0; + struct device_ioctl dio; + + while ((ch = getopt(argc, argv, "rs")) != -1) { + switch (ch) { + case 'r': + rflag++; + break; + case 's': + sflag++; + break; + default: + usage(); + } + } + if (rflag + sflag != 1) + errx(1, "You must specify exactly one of -r and -s"); + argv += optind; + argc -= optind; + if (argc < 2) + usage(); + fd = open("/dev/devctl", O_RDWR); + if (fd == -1) + err(1, "Opening /dev/devctl"); + strcpy(dio.dio_devclass, argv[0]); + dio.dio_unit = strtol(argv[1], NULL, 0); + if (rflag) { + if (ioctl(fd, DEVIOC_RESUME, &dio) == -1) + err(1, "DEVIOC_RESUME"); + } else { + if (ioctl(fd, DEVIOC_SUSPEND, &dio) == -1) + err(1, "DEVIOC_RESUME"); + } +}