Attempting to sleep in interrupts

M. Warner Losh imp at bsdimp.com
Tue Nov 8 11:18:34 PST 2005


Does this solve the problem?

Warner

Index: subr_power.c
===================================================================
RCS file: /cache/ncvs/src/sys/kern/subr_power.c,v
retrieving revision 1.5
diff -u -r1.5 subr_power.c
--- subr_power.c	2 Jan 2004 18:24:13 -0000	1.5
+++ subr_power.c	8 Nov 2005 19:17:54 -0000
@@ -32,10 +32,20 @@
 #include <sys/proc.h>
 
 #include <sys/power.h>
+#include <sys/taskqueue.h>
 
 static u_int		 power_pm_type	= POWER_PM_TYPE_NONE;
 static power_pm_fn_t	 power_pm_fn	= NULL;
 static void		*power_pm_arg	= NULL;
+static struct task	 power_pm_task;
+
+static void
+power_pm_deferred_fn(void *arg, int pending)
+{
+	int state = (int)arg;
+
+	power_pm_fn(POWER_CMD_SUSPEND, power_pm_arg, state);
+}
 
 int
 power_pm_register(u_int pm_type, power_pm_fn_t pm_fn, void *pm_arg)
@@ -48,6 +58,7 @@
 		power_pm_fn	= pm_fn;
 		power_pm_arg	= pm_arg;
 		error = 0;
+		TASK_INIT(&power_pm_task, 0, power_pm_deferred_fn, NULL);
 	} else {
 		error = ENXIO;
 	}
@@ -72,8 +83,8 @@
 	    state != POWER_SLEEP_STATE_SUSPEND &&
 	    state != POWER_SLEEP_STATE_HIBERNATE)
 		return;
-
-	power_pm_fn(POWER_CMD_SUSPEND, power_pm_arg, state);
+	power_pm_task.ta_context = (void *)state;
+	taskqueue_enqueue(taskqueue_swi, &power_pm_task);
 }
 
 /*


More information about the freebsd-current mailing list