summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPaul Irofti <pirofti@cvs.openbsd.org>2009-11-22 18:40:14 +0000
committerPaul Irofti <pirofti@cvs.openbsd.org>2009-11-22 18:40:14 +0000
commit832a4e0700eb0aaa6224480c77007423742a2654 (patch)
tree8fcdba4159007528eeca527caf454b9e9aa16ea0 /sys
parent7214e153c6803bef90d67532be57bf02fe908165 (diff)
Add basic suspend/resume autoconf functionality.
Okay deraadt@, kettenis@, mlarkin@.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/subr_autoconf.c44
-rw-r--r--sys/sys/device.h5
2 files changed, 47 insertions, 2 deletions
diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c
index df7c6a5ba9d..3ef78645ab4 100644
--- a/sys/kern/subr_autoconf.c
+++ b/sys/kern/subr_autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_autoconf.c,v 1.57 2009/10/13 19:33:19 pirofti Exp $ */
+/* $OpenBSD: subr_autoconf.c,v 1.58 2009/11/22 18:40:13 pirofti Exp $ */
/* $NetBSD: subr_autoconf.c,v 1.21 1996/04/04 06:06:18 cgd Exp $ */
/*
@@ -641,6 +641,42 @@ config_deactivate(struct device *dev)
return (rv);
}
+int
+config_suspend(struct device *dev)
+{
+ struct cfattach *ca = dev->dv_cfdata->cf_attach;
+ int rv = 0, oflags = dev->dv_flags;
+
+ if (ca->ca_activate == NULL)
+ return (EOPNOTSUPP);
+
+ if ((dev->dv_flags & DVF_SUSPEND) == 0) {
+ dev->dv_flags |= DVF_SUSPEND;
+ rv = (*ca->ca_activate)(dev, DVACT_SUSPEND);
+ if (rv)
+ dev->dv_flags = oflags;
+ }
+ return (rv);
+}
+
+int
+config_resume(struct device *dev)
+{
+ struct cfattach *ca = dev->dv_cfdata->cf_attach;
+ int rv = 0, oflags = dev->dv_flags;
+
+ if (ca->ca_activate == NULL)
+ return (EOPNOTSUPP);
+
+ if (dev->dv_flags & DVF_SUSPEND) {
+ dev->dv_flags &= ~DVF_SUSPEND;
+ rv = (*ca->ca_activate)(dev, DVACT_RESUME);
+ if (rv)
+ dev->dv_flags = oflags;
+ }
+ return (rv);
+}
+
/*
* Defer the configuration of the specified device until all
* of its parent's devices have been attached.
@@ -768,6 +804,12 @@ config_activate_children(struct device *parent, int act)
case DVACT_DEACTIVATE:
rv = config_deactivate(dev);
break;
+ case DVACT_SUSPEND:
+ rv = config_suspend(dev);
+ break;
+ case DVACT_RESUME:
+ rv = config_resume(dev);
+ break;
default:
#ifdef DIAGNOSTIC
printf ("config_activate_children: shouldn't get here");
diff --git a/sys/sys/device.h b/sys/sys/device.h
index 8ae891d0526..e2201ddcec9 100644
--- a/sys/sys/device.h
+++ b/sys/sys/device.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: device.h,v 1.38 2009/10/13 19:33:19 pirofti Exp $ */
+/* $OpenBSD: device.h,v 1.39 2009/11/22 18:40:13 pirofti Exp $ */
/* $NetBSD: device.h,v 1.15 1996/04/09 20:55:24 cgd Exp $ */
/*
@@ -64,6 +64,8 @@ enum devclass {
*/
#define DVACT_ACTIVATE 0 /* activate the device */
#define DVACT_DEACTIVATE 1 /* deactivate the device */
+#define DVACT_SUSPEND 2 /* suspend the device */
+#define DVACT_RESUME 3 /* resume the device */
struct device {
enum devclass dv_class; /* this device's classification */
@@ -78,6 +80,7 @@ struct device {
/* dv_flags */
#define DVF_ACTIVE 0x0001 /* device is activated */
+#define DVF_SUSPEND 0x0002 /* device is suspended */
TAILQ_HEAD(devicelist, device);