From owner-acpi-jp@jp.freebsd.org  Sun Sep  3 11:00:41 2000
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id LAA94878;
	Sun, 3 Sep 2000 11:00:41 +0900 (JST)
	(envelope-from owner-acpi-jp@jp.FreeBSD.org)
Received: from tasogare.imasy.or.jp (daemon@tasogare.imasy.or.jp [202.227.24.5])
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) with ESMTP id LAA94873
	for <acpi-jp@jp.freebsd.org>; Sun, 3 Sep 2000 11:00:41 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
Received: from localhost (iwasaki.imasy.or.jp [202.227.24.92])
	by tasogare.imasy.or.jp (8.10.2+3.3W/3.7W-tasogare/smtpfeed 1.07) with ESMTP id e8320cr96523
	for <acpi-jp@jp.freebsd.org>; Sun, 3 Sep 2000 11:00:38 +0900 (JST)
	(envelope-from iwasaki@jp.FreeBSD.org)
To: acpi-jp@jp.freebsd.org
X-Mailer: Mew version 1.94.1 on Emacs 19.34 / Mule 2.3 (SUETSUMUHANA)
Mime-Version: 1.0
Content-Type: Text/Plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
Message-Id: <20000903110017W.iwasaki@jp.FreeBSD.org>
Date: Sun, 03 Sep 2000 11:00:17 +0900
From: Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
X-Dispatcher: imput version 20000228(IM140)
Lines: 391
Reply-To: acpi-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+000315
X-Sequence: acpi-jp 606
Subject: [acpi-jp 606] acpi_send_pm_event()
Errors-To: owner-acpi-jp@jp.freebsd.org
Sender: owner-acpi-jp@jp.freebsd.org
X-Originator: iwasaki@jp.freebsd.org

$B0JA0$b=q$-$^$7$?$,!"(BChandra2 $B$N(B S1 state $B$O(B apm $B$N(B suspend $B$HEy2A$G$9!#(B
$B$H$$$&$o$1$G!"(Bacpiconf -s 1 $B$7$?:]$K(B apm_suspend() $B$HF1MM$K(B 
DEVICE_SUSPEND(root_bus) $B$r8F$s$G3F%G%P%$%9B&$N(B suspend $B=hM}$r(B
$B$*$3$J$o$;$k$h$&$K$7$h$&$H$7$F$$$^$9!#(B

$BD94|E*$K$O(B
 - APM $B$K0MB8$7$?(B DEVICE_{SUSPEND|RESUME}() $B$rGQ;_$7!"(BACPI $B$N(B $BB?CJ3,$N(B
   system sleeping state $B$KBP1~$7$?F1MM$N;EAH$_$r:n$j!"(BAPM $BB&$b$=$l$r(B
   $BMxMQ$9$k(B
 - $B3F%$%Y%s%H$d(B sleeping state $BA+0\$H<B:]$N=hM}$H$NBP1~IU$1$r(B Policy
   Manager $B$,4IM}$9$k(B (apmd $B$d(B pccardd $B$d(B usbd $B$r$b$C$HHFMQE*$K$7$F(B
   $BJXMx$K$9$k(B)
$B$H$$$C$?$3$H$r$d$j$?$$$N$G$9$,!"$H$j$"$($:(B
 - acpiconf -s 1 $B$N;~$b(B PCCard $B$N(B detach $B$J$I$b$d$j$?$$(B
	-> acpi.c $B$NCf$G(B DEVICE_{SUSPEND|RESUME}() $B$r8F$V(B
 - acpiconf -s 1 $B$N;~$b(B timer $B$N:F=i4|2=$,$7$?$$(B
	-> apm_default_{suspend|resume} $B$N(B timer $B$N=hM}$r(B
	   i386/isa/clock.c $B$X(B device_{suspend|resume} $B$N(B 
	   method $B$H$7$F0\F0!#(Binstance $B$,J#?t$N>l9g$b$"$k$,5$$K$7$J$$(B (^^;
 - acpiconf -s 1 $B$+$iLa$C$F$-$?:]$K(B APM suspend $B$7$J$+$C$?$K$b4X$o$i$:(B
   APM resume event $B$bH/@8$7(B DEVICE_RESUME() $B$r:F$S8F$\$&$H$9$k$,!"$3$N>l9g(B
   APM $BB&$G$O$3$l$rL5;k$9$k!#(B
$B$H$$$C$?$3$H$r$d$j$^$7$?!#(Bdiffs $B$rIU$1$^$9$N$G$40U8+;r$j$?$/!#(B
# acpi $B$G$b@83h46$,=P$F$-$?(B :-)

acpiconf -s 1 $B$r<B9T$7$?:]$N%m%0(B:
Sep  3 09:52:43 chandra2 /kernel: wi0: unload
Sep  3 09:52:43 chandra2 /kernel: wi0: detached
Sep  3 09:52:43 chandra2 /kernel: stray irq 9
Sep  3 09:52:43 chandra2 /kernel: pccard: card disabled, slot 2
Sep  3 09:52:43 chandra2 /kernel: acpi0: acpi_io_pm1_status(0) = (411, 0)
Sep  3 09:52:43 chandra2 /kernel: acpi0: wake-up logic seems broken, this may cause troubles on wakeup
Sep  3 09:52:43 chandra2 /kernel: acpi0: acpi_io_pm1_status(1) = (8000, 8000)
Sep  3 09:52:43 chandra2 /kernel: acpi0: acpi_io_pm1_control(0) = (1, 0)
Sep  3 09:52:43 chandra2 /kernel: acpi0: acpi_io_pm1_control(1) = (2401, 2400)
Sep  3 09:52:43 chandra2 /kernel: pccard: card inserted, slot 2
Sep  3 09:52:43 chandra2 /kernel: ata0: resetting devices .. done
Sep  3 09:52:43 chandra2 /kernel: acpi0: ACPIIO_SETSLPSTATE = 1
Sep  3 09:52:43 chandra2 dhclient: receive_packet failed on wi0: Device not configured
Sep  3 09:52:48 chandra2 last message repeated 5899 times
Sep  3 09:52:48 chandra2 pccardd[113]: Card "MELCO"("WLI-PCM-L11") [Version 01.01] [] matched "MELCO" ("WLI-PCM-L11") [(null)] [(null)] 
($B0J2<N,(B)

apm -z $B$r<B9T$7$?:]$N%m%0(B:
Sep  3 09:55:55 chandra2 /kernel: wi0: unload
Sep  3 09:55:55 chandra2 /kernel: wi0: detached
Sep  3 09:55:55 chandra2 /kernel: stray irq 9
Sep  3 09:55:55 chandra2 /kernel: pccard: card disabled, slot 2
Sep  3 09:55:55 chandra2 /kernel: pccard: card inserted, slot 2
Sep  3 09:55:55 chandra2 /kernel: ata0: resetting devices .. done
Sep  3 09:55:55 chandra2 dhclient: receive_packet failed on wi0: Device not conf
igured
Sep  3 09:56:00 chandra2 last message repeated 5909 times
Sep  3 09:56:00 chandra2 pccardd[113]: Card "MELCO"("WLI-PCM-L11") [Version 01.01] [] matched "MELCO" ("WLI-PCM-L11") [(null)] [(null)] 
($B0J2<N,(B)


Index: dev/acpi/acpi.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.7
diff -u -r1.7 acpi.c
--- dev/acpi/acpi.c	2000/09/02 15:06:22	1.7
+++ dev/acpi/acpi.c	2000/09/03 00:57:28
@@ -36,6 +36,9 @@
 #include <sys/conf.h>
 #include <sys/sysctl.h>
 
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
 #include <sys/eventhandler.h>		/* for EVENTHANDLER_REGISTER */
 #include <sys/reboot.h>			/* for RB_POWEROFF */
 #include <machine/clock.h>		/* for DELAY */
@@ -153,6 +156,7 @@
 
 /* New-bus dependent code */
 static acpi_softc_t *acpi_get_softc(dev_t dev);
+static int  acpi_send_pm_event(acpi_softc_t *sc, u_int8_t state);
 static void acpi_identify(driver_t *driver, device_t parent);
 static int  acpi_probe(device_t dev);
 static int  acpi_attach(device_t dev);
@@ -680,6 +684,7 @@
 	}
 
 	/* get sleeping type values from ACPI namespace */
+	sc->system_state = ACPI_S_STATE_S0;
 	sc->system_state_initialized = 1;
 	for (i = ACPI_S_STATE_S0; i <= ACPI_S_STATE_S5; i++) {
 		ssp.mode[i].slp_typ_a = ACPI_UNSUPPORTSLPTYP;
@@ -907,11 +912,20 @@
 		/* Prepare to sleep */
 		acpi_execute_pts(sc, state);
 
+		/* inform all devices that we are going to sleep. */
+		if (acpi_send_pm_event(sc, state) != 0) {
+			/* if failure, 'wakeup' the system again */
+			acpi_send_pm_event(sc, ACPI_S_STATE_S0);
+			return;
+		}
+
 		/* PowerResource manipulation */
 		acpi_powerres_set_sleeping_state(sc, state);
 		if (acpi_debug) {
 			acpi_powerres_debug(sc);
 		}
+
+		sc->system_state = state;
 	}
 
 	/*
@@ -932,10 +946,13 @@
 
 	if (state < ACPI_S_STATE_S5) {
 		acpi_execute_wak(sc, state);
+		acpi_send_pm_event(sc, ACPI_S_STATE_S0);
 		acpi_powerres_set_sleeping_state(sc, 0);
 		if (acpi_debug) {
 			acpi_powerres_debug(sc);
 		}
+
+		sc->system_state = ACPI_S_STATE_S0;
 	}
 }
 
@@ -1231,6 +1248,31 @@
 {
 
 	return (devclass_get_softc(acpi_devclass, minor(dev)));
+}
+
+static int
+acpi_send_pm_event(acpi_softc_t *sc, u_int8_t state)
+{
+	int	error;
+
+	error = 0;
+	switch (state) {
+	case ACPI_S_STATE_S0:
+		if (sc->system_state != ACPI_S_STATE_S0) {
+			DEVICE_RESUME(root_bus);
+		}
+		break;
+	case ACPI_S_STATE_S1:
+	case ACPI_S_STATE_S2:
+	case ACPI_S_STATE_S3:
+	case ACPI_S_STATE_S4:
+		error = DEVICE_SUSPEND(root_bus);
+		break;
+	default:
+		break;
+	}
+
+	return (error);
 }
 
 static void
Index: dev/acpi/acpi.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/acpi/acpi.h,v
retrieving revision 1.2
diff -u -r1.2 acpi.h
--- dev/acpi/acpi.h	2000/08/29 20:38:31	1.2
+++ dev/acpi/acpi.h	2000/09/02 14:05:41
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD$
+ *	$FreeBSD: src/sys/dev/acpi/acpi.h,v 1.2 2000/08/29 20:38:31 iwasaki Exp $
  */
 
 #ifndef _DEV_ACPI_ACPI_H_
@@ -53,7 +53,7 @@
 #define ACPI_POWER_RESOURCE_ON	1
 #define ACPI_POWER_RESOURCE_OFF	0
 	u_int8_t	state;		/* OFF or ON */
-#define ACPI_PR_MAX		3
+#define ACPI_PR_MAX		3	/* _PR[0-2] */
 	LIST_HEAD(, acpi_powerres_device_ref) reflist[ACPI_PR_MAX];
 };
 
@@ -64,6 +64,7 @@
 	struct	FACPbody *facp_body;
 	struct	ACPIsdt *dsdt;
 	struct	FACS *facs;
+	int	system_state;
 	int	system_state_initialized;
 	int	broken_wakeuplogic;
 	struct	acpi_system_state_package system_state_package;
@@ -84,4 +85,4 @@
 				         u_int8_t);
 void		 acpi_powerres_set_sleeping_state(acpi_softc_t *, u_int8_t);
 
-#endif	/* _DEV_ACPI_ACPI_H_ */
+#endif	/* !_DEV_ACPI_ACPI_H_ */
Index: i386//apm/apm.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/apm/apm.c,v
retrieving revision 1.117
diff -u -r1.117 apm.c
--- i386//apm/apm.c	2000/08/13 17:05:26	1.117
+++ i386//apm/apm.c	2000/09/03 00:38:22
@@ -402,69 +402,6 @@
 	apm_del_hook(&hook[apmh], ah);
 }
 
-
-static struct timeval suspend_time;
-static struct timeval diff_time;
-
-static int
-apm_default_resume(void *arg)
-{
-	int pl;
-	u_int second, minute, hour;
-	struct timeval resume_time, tmp_time;
-
-	/* modified for adjkerntz */
-	pl = splsoftclock();
-	i8254_restore();		/* restore timer_freq and hz */
-	inittodr(0);			/* adjust time to RTC */
-	microtime(&resume_time);
-	getmicrotime(&tmp_time);
-	timevaladd(&tmp_time, &diff_time);
-
-#ifdef FIXME
-	/* XXX THIS DOESN'T WORK!!! */
-	time = tmp_time;
-#endif
-
-#ifdef APM_FIXUP_CALLTODO
-	/* Calculate the delta time suspended */
-	timevalsub(&resume_time, &suspend_time);
-	/* Fixup the calltodo list with the delta time. */
-	adjust_timeout_calltodo(&resume_time);
-#endif /* APM_FIXUP_CALLTODOK */
-	splx(pl);
-#ifndef APM_FIXUP_CALLTODO
-	second = resume_time.tv_sec - suspend_time.tv_sec; 
-#else /* APM_FIXUP_CALLTODO */
-	/* 
-	 * We've already calculated resume_time to be the delta between 
-	 * the suspend and the resume. 
-	 */
-	second = resume_time.tv_sec; 
-#endif /* APM_FIXUP_CALLTODO */
-	hour = second / 3600;
-	second %= 3600;
-	minute = second / 60;
-	second %= 60;
-	log(LOG_NOTICE, "resumed from suspended mode (slept %02d:%02d:%02d)\n",
-		hour, minute, second);
-	return 0;
-}
-
-static int
-apm_default_suspend(void *arg)
-{
-	int	pl;
-
-	pl = splsoftclock();
-	microtime(&diff_time);
-	inittodr(0);
-	microtime(&suspend_time);
-	timevalsub(&diff_time, &suspend_time);
-	splx(pl);
-	return 0;
-}
-
 static int apm_record_event __P((struct apm_softc *, u_int));
 static void apm_processevent(void);
 
@@ -489,6 +426,7 @@
 		} else {
 			apm_execute_hook(hook[APM_HOOK_SUSPEND]);
 			if (apm_suspend_system(PMST_SUSPEND) == 0) {
+				sc->suspending = 1;
 				apm_processevent();
 			} else {
 				/* Failure, 'resume' the system again */
@@ -515,7 +453,6 @@
 		 * As far as standby, we don't need to execute 
 		 * all of suspend hooks.
 		 */
-		apm_default_suspend(&apm_softc);
 		if (apm_suspend_system(PMST_STANDBY) == 0)
 			apm_processevent();
 	}
@@ -600,6 +537,10 @@
 	if (!sc)
 		return;
 
+	if (sc->suspending == 0)
+		return;
+
+	sc->suspending = 0;
 	if (sc->initialized) {
 		apm_execute_hook(hook[APM_HOOK_RESUME]);
 		DEVICE_RESUME(root_bus);
@@ -1095,26 +1036,12 @@
 		}
 	}
 
-        /* default suspend hook */
-        sc->sc_suspend.ah_fun = apm_default_suspend;
-        sc->sc_suspend.ah_arg = sc;
-        sc->sc_suspend.ah_name = "default suspend";
-        sc->sc_suspend.ah_order = APM_MAX_ORDER;
-
-        /* default resume hook */
-        sc->sc_resume.ah_fun = apm_default_resume;
-        sc->sc_resume.ah_arg = sc;
-        sc->sc_resume.ah_name = "default resume";
-        sc->sc_resume.ah_order = APM_MIN_ORDER;
-
-        apm_hook_establish(APM_HOOK_SUSPEND, &sc->sc_suspend);
-        apm_hook_establish(APM_HOOK_RESUME , &sc->sc_resume);
-
 	/* Power the system off using APM */
 	EVENTHANDLER_REGISTER(shutdown_final, apm_power_off, NULL, 
 			      SHUTDOWN_PRI_LAST);
 
 	sc->initialized = 1;
+	sc->suspending = 0;
 
 	make_dev(&apm_cdevsw, 0, 0, 5, 0660, "apm");
 	make_dev(&apm_cdevsw, 8, 0, 5, 0660, "apmctl");
Index: i386//apm/apm.h
===================================================================
RCS file: /home/ncvs/src/sys/i386/apm/apm.h,v
retrieving revision 1.1
diff -u -r1.1 apm.h
--- i386//apm/apm.h	1999/10/02 03:34:15	1.1
+++ i386//apm/apm.h	2000/09/02 17:11:25
@@ -26,6 +26,7 @@
 	int	initialized, active, bios_busy;
 	int	always_halt_cpu, slow_idle_cpu;
 	int	disabled, disengaged;
+	int	suspending;
 	int	standby_countdown, suspend_countdown;
 	u_int	minorversion, majorversion;
 	u_int	intversion, connectmode;
Index: i386//isa/clock.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/isa/clock.c,v
retrieving revision 1.155
diff -u -r1.155 clock.c
--- i386//isa/clock.c	2000/07/30 21:05:22	1.155
+++ i386//isa/clock.c	2000/09/03 01:25:27
@@ -1262,14 +1262,38 @@
 	return(0);
 }
 
+static int
+attimer_suspend(device_t dev)
+{
+	int	pl;
+
+	pl = splsoftclock();
+	inittodr(0);
+	splx(pl);
+	return (0);
+}
+
+static int
+attimer_resume(device_t dev)
+{
+	int pl;
+
+	/* modified for adjkerntz */
+	pl = splsoftclock();
+	i8254_restore();		/* restore timer_freq and hz */
+	inittodr(0);			/* adjust time to RTC */
+	splx(pl);
+	return (0);
+}
+
 static device_method_t attimer_methods[] = {
 	/* Device interface */
 	DEVMETHOD(device_probe,		attimer_probe),
 	DEVMETHOD(device_attach,	attimer_attach),
 	DEVMETHOD(device_detach,	bus_generic_detach),
 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
-	DEVMETHOD(device_suspend,	bus_generic_suspend),	/* XXX stop statclock? */
-	DEVMETHOD(device_resume,	bus_generic_resume),	/* XXX restart statclock? */
+	DEVMETHOD(device_suspend,	attimer_suspend),
+	DEVMETHOD(device_resume,	attimer_resume),
 	{ 0, 0 }
 };
 
