i've been interested in using/having/writing an ACPI suspend support in
OpenBSD, so i how is the progress of it at the moment? What should be
properly done for it to work?
Looks like FreeBSD has its basic s2ram implementation, how hard is it to
port it into OpenBSD?
Thanks for answers in advance,
--
Vladimir Kirillov
Suspend is not the hard part... :)
--Toby.
Resume doesn't work for me. I've "fixed" a couple things in acpi_resume()
that caused my system to crash, but when I resume my (laptop) display
doesn't come back on..... Dunno why...
Fan starts up, dvd drive spins up, lights come on, but no display.
I've started looking at suspend/resume to see how it works but maybe a
developer could clue me in on what needs to be done? Or at least where I
should start looking?
and how did you test it? uncommented some code? some compile options?
apm -S just does nothing.
(i've found acpi_resume commented out by cpp in /sys/dev/acpi/acpi.c
then i've found acpi_enter_sleep_state(), so how should it be called
right from userland?)
--
Vladimir Kirillov
Check your driver for ACPI hotkeys.
E.g. on thinkpads, there is the acpithinkpad driver,
which currently does the following (i.e. nothing)
for the suspend button:
case THINKPAD_BUTTON_SUSPEND:
handled = 1;
/*
acpi_enter_sleep_state(sc->sc_acpi,
ACPI_STATE_S3);
*/
break;
I haven't tried to enable this yet, assuming there will
be a call for testers once people start to try to make
this work.
Stefan
ok, i'll try with the acpibtn then.
--
Vladimir Kirillov
First things first, you need this diff as a bare minimum:
Index: acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.125
diff -u -p -r1.125 acpi.c
--- acpi.c 2 Jul 2008 03:14:54 -0000 1.125
+++ acpi.c 20 Sep 2008 12:24:11 -0000
@@ -1662,6 +1662,7 @@ acpi_enter_sleep_state(struct acpi_softc
if (state == ACPI_STATE_S0)
return;
+
if (sc->sc_sleeptype[state].slp_typa == -1 ||
sc->sc_sleeptype[state].slp_typb == -1) {
printf("%s: state S%d unavailable\n",
@@ -1670,8 +1671,10 @@ acpi_enter_sleep_state(struct acpi_softc
}
memset(&env, 0, sizeof(env));
+
env.type = AML_OBJTYPE_INTEGER;
env.v_integer = state;
+
/* _TTS(state) */
if (sc->sc_tts) {
if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) {
@@ -1680,6 +1683,7 @@ acpi_enter_sleep_state(struct acpi_softc
return;
}
}
+
switch (state) {
case ACPI_STATE_S1:
case ACPI_STATE_S2:
@@ -1690,7 +1694,13 @@ acpi_enter_sleep_state(struct acpi_softc
resettodr();
dopowerhooks(PWR_STANDBY);
break;
+ case ACPI_STATE_S4:
+ case ACPI_STATE_S5:
+ return;
+ default:
+ return;
}
+
/* _PTS(state) */
if (sc->sc_pts) {
if (aml_evalnode(sc, sc->sc_pts, 1, &env, NULL) != 0) {
@@ -1699,7 +1709,9 @@ acpi_enter_sleep_state(struct acpi_softc
return;
}
}
+
sc->sc_state = state;
+
/* _GTS(state) */
if (sc->sc_gts) {
if (aml_evalnode(sc, sc->sc_gts, 1, &env, NULL) != 0) {
@@ -1708,6 +1720,7 @@ acpi_enter_sleep_state(struct acpi_softc
return;
}
}
+
disable_intr();
/* Clear WAK_STS bit */
@@ -1742,34 +1755,39 @@ acpi_enter_sleep_state(struct acpi_softc
enable_intr();
}
-#if 0
+#if 1
void
acpi_resume(struct acpi_softc *sc)
{
struct aml_value env;
memset(&env, 0, sizeof(env));
+
env.type = AML_OBJTYPE_INTEGER;
env.v_integer = sc->sc_state;
if (sc->sc_bfs) {
- if (aml_evalnode(sc, sc->sc_pts, 1, &env, NULL) != 0) {
+ if (aml_evalnode(sc, sc->sc_bfs, 1, &env, NULL) != 0) {
dnprintf(10, "%s evaluating method _BFS failed.\n",
DEVNAME(sc));
}
}
- dopowerhooks(PWR_RESUME);
- inittodr(0);
+
if (sc->sc_wak) {
if (aml_evalnode(sc, sc->sc_wak, 1, &env, NULL) != 0) {
dnprintf(10, "%s evaluating method _WAK failed.\n",
DEVNAME(sc));
}
}
+
+ dopowerhooks(PWR_RESUME);
+ inittodr(0);
+
sc->sc_state = ACPI_STATE_S0;
+
if (sc->sc_tts) {
env.v_integer = sc->sc_state;
- if (aml_evalnode(sc, sc->sc_wak, 1, &env, NULL) != 0) {
+ if (aml_evalnode(sc, sc->sc_tts, 1, &env, NULL) != 0) {
dnprintf(10, "%s evaluating method _TTS failed.\n",
DEVNAME(sc));
}
I hacked up an acpilid driver to support lid open/close.
So when I close my laptop's lid it sleeps and when I open the lid it
resumes.
My laptop suspends fine but it doesn't resume correctly.
With the above diff at least my laptop doesn't reboot if you try to enter
the S4, S5 sleep states.
Also acpi_resume() was doing aml_evalnode() on the wrong methods....
> apm -S just does nothing
apm zzz does nothing here either but I think that is because apmd isn't
running.
Maybe you don't have ampd running?
i've got this diff (by myself):
Index: acpi/acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.125
diff -u -p -r1.125 acpi.c
--- acpi/acpi.c 2 Jul 2008 03:14:54 -0000 1.125
+++ acpi/acpi.c 20 Sep 2008 19:10:04 -0000
@@ -1742,7 +1742,6 @@ acpi_enter_sleep_state(struct acpi_softc
enable_intr();
}
-#if 0
void
acpi_resume(struct acpi_softc *sc)
{
@@ -1775,7 +1774,6 @@ acpi_resume(struct acpi_softc *sc)
}
}
}
-#endif
void
acpi_powerdown(void)
Index: acpi/acpibtn.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpibtn.c,v
retrieving revision 1.19
diff -u -p -r1.19 acpibtn.c
--- acpi/acpibtn.c 1 Jun 2008 17:59:55 -0000 1.19
+++ acpi/acpibtn.c 20 Sep 2008 19:10:04 -0000
@@ -124,11 +124,15 @@ acpibtn_notify(struct aml_node *node, in
switch (sc->sc_btn_type) {
case ACPIBTN_LID:
+ printf("ACPI LID NOTIFY\n");
+ break;
case ACPIBTN_SLEEP:
break;
case ACPIBTN_POWER:
+ printf("ACPIBTN_POWER NOTIFY\n");
if (notify_type == 0x80)
- psignal(initproc, SIGUSR2);
+ acpi_enter_sleep_state(sc->sc_acpi, ACPI_STATE_S3);
+ /* psignal(initproc, SIGUSR2); */
break;
default:
printf("%s: spurious acpi button interrupt %i\n", DEVNAME(sc),
Index: acpi/acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.43
diff -u -p -r1.43 acpivar.h
--- acpi/acpivar.h 15 Sep 2008 19:25:36 -0000 1.43
+++ acpi/acpivar.h 20 Sep 2008 19:10:04 -0000
@@ -22,7 +22,7 @@
#include <sys/rwlock.h>
#include <machine/biosvar.h>
-/* #define ACPI_DEBUG */
+#define ACPI_DEBUG
#ifdef ACPI_DEBUG
extern int acpi_debug;
#define dprintf(x...) do { if (acpi_debug) printf(x); } while (0)
> I hacked up an acpilid driver to support lid open/close.
> So when I close my laptop's lid it sleeps and when I open the lid it
> resumes.
i've replaced acpibtn's power button to do acpi_enter_sleep_state()
it suspends for me but resuming doesn't return me the console (tryed
with no X)
> My laptop suspends fine but it doesn't resume correctly.
> With the above diff at least my laptop doesn't reboot if you try to enter
> the S4, S5 sleep states.
my laptop didn't reboot without changes in acpi_resume() (just
uncommented it)
> Also acpi_resume() was doing aml_evalnode() on the wrong methods....
> > apm -S just does nothing
>
> apm zzz does nothing here either but I think that is because apmd isn't
> running.
> Maybe you don't have ampd running?
>
no, apmd is okay, it just doesn't do acpi suspend :)
[proger][~] 0 $ apm -S
System will enter standby mode momentarily.
# --- the above has no effect
any ideas (checklist?) about what should be done for the right resume?
--
Vladimir Kirillov
I didn't say acpi_resume() was causing the reboot.
I passed ACPI_STATE_S4/S5 to acpi_enter_sleep_state() and I get a reboot
(file system improperly unmounted etc.).
So since OpenBSD doesn't support those sleep states yet (S4/S5) the diff
prevents that (return).
In any case, like I said before acpi_resume() is doing aml_evalname() on the
wrong methods....
Which my diff corrects. :)
Welcome to the club. :) Anyways, in order for your display to work,
chances are you're going to need the vm86 stuff to call the display
bios and re-initialize the display into a fashion that X can then use
as a starting point to re-init/whatever to get graphics back.
> I've started looking at suspend/resume to see how it works but maybe a
> developer could clue me in on what needs to be done? Or at least where I
> should start looking?
In part, you basically need to get hardware back into the state it
was in before you went to sleep. That might involve doing a partial
autoconf run, letting the drivers know you're coming back from sleep.
-Toby.
//art
Is it possible to see any patches right now for study/researches?
> but don't hold your breath.
why? :)
--
Vladimir Kirillov
> On 10:13 Tue 23 Sep, Artur Grabowski wrote:
>> There is some work being done right now. Some machines are barely able to
>> do suspend and resume,
>
> Is it possible to see any patches right now for study/researches?
Poke marco@. I would like to see the latest patches too, but he's a
slacker. :)
>> but don't hold your breath.
> why? :)
Because it's a mess. Getting the cpu to start running is easy enough.
Getting all devices to a known state is a PITA.
//art