> Another possibility is *delay mechanism* on suspend (and standby).
> AFAIK, Linux, NetBSD and PAO has this but CURRENT. I'll make patch
> tonight based on PAO APM code.
Please try this patch.
If it still fails, it's worth to try increasing APM_SUSPEND_DELAY,
something like:
#define APM_SUSPEND_DELAY 3
plm> or with the suspend button or through the BIOS timer), the led starts
Oh, do you have suspend button on your box? Cool.
On my poor experience, suspeding by hot-keys easier to
success than by zzz(8).
BTW, have you tried apmd too?
Index: apm.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/apm/apm.c,v
retrieving revision 1.98
diff -u -r1.98 apm.c
--- apm.c 1999/08/02 18:46:34 1.98
+++ apm.c 1999/08/10 14:05:43
@@ -63,8 +63,10 @@
int initialized, active, bios_busy;
int always_halt_cpu, slow_idle_cpu;
int disabled, disengaged;
+ int standby_countdown, suspend_countdown;
u_int minorversion, majorversion;
u_int intversion, connectmode;
+ u_int standbys, suspends;
struct bios_args bios;
struct apmhook sc_suspend;
struct apmhook sc_resume;
@@ -431,7 +433,68 @@
static u_int apm_op_inprog = 0;
+/* This is no good :( This should be SYSCTLized. */
+#ifndef APM_STANDBY_DELAY
+#define APM_STANDBY_DELAY 1
+#endif
+
+#ifndef APM_SUSPEND_DELAY
+#define APM_SUSPEND_DELAY 1
+#endif
+
static void
+apm_do_suspend(void)
+{
+ struct apm_softc *sc = &apm_softc;
+ int error;
+
+ if (!sc)
+ return;
+
+ apm_op_inprog = 0;
+ sc->suspends = sc->suspend_countdown = 0;
+
+ if (sc->initialized) {
+ error = DEVICE_SUSPEND(root_bus);
+ /*
+ * XXX Shouldn't ignore the error like this, but should
+ * instead fix the newbus code. Until that happens,
+ * I'm doing this to get suspend working again.
+ */
+ if (error)
+ printf("DEVICE_SUSPEND error %d, ignored\n", error);
+ apm_execute_hook(hook[APM_HOOK_SUSPEND]);
+ if (apm_suspend_system(PMST_SUSPEND) == 0)
+ apm_processevent();
+ else
+ /* Failure, 'resume' the system again */
+ apm_execute_hook(hook[APM_HOOK_RESUME]);
+ }
+}
+
+static void
+apm_do_standby(void)
+{
+ struct apm_softc *sc = &apm_softc;
+
+ if (!sc)
+ return;
+
+ apm_op_inprog = 0;
+ sc->standbys = sc->standby_countdown = 0;
+
+ if (sc->initialized) {
+ /*
+ * 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();
+ }
+}
+
+static void
apm_lastreq_notify(void)
{
struct apm_softc *sc = &apm_softc;
@@ -478,29 +541,27 @@
apm_suspend(int state)
{
struct apm_softc *sc = &apm_softc;
- int error;
- if (!sc)
+ switch (state) {
+ case PMST_SUSPEND:
+ if (sc->suspends)
+ return;
+ sc->suspends++;
+ sc->suspend_countdown = APM_SUSPEND_DELAY;
+ break;
+ case PMST_STANDBY:
+ if (sc->standbys)
+ return;
+ sc->standbys++;
+ sc->standby_countdown = APM_STANDBY_DELAY;
+ break;
+ default:
+ printf("apm_suspend: Unknown Suspend state 0x%x\n", state);
return;
-
- apm_op_inprog = 0;
-
- if (sc->initialized) {
- error = DEVICE_SUSPEND(root_bus);
- /*
- * XXX Shouldn't ignore the error like this, but should
- * instead fix the newbus code. Until that happens,
- * I'm doing this to get suspend working again.
- */
- if (error)
- printf("DEVICE_SUSPEND error %d, ignored\n", error);
- apm_execute_hook(hook[APM_HOOK_SUSPEND]);
- if (apm_suspend_system(state) == 0)
- apm_processevent();
- else
- /* Failure, 'resume' the system again */
- apm_execute_hook(hook[APM_HOOK_RESUME]);
}
+
+ apm_op_inprog++;
+ apm_lastreq_notify();
}
void
@@ -625,6 +686,12 @@
if (apm_op_inprog)
apm_lastreq_notify();
+ if (sc->standbys && sc->standby_countdown-- <= 0)
+ apm_do_standby();
+
+ if (sc->suspends && sc->suspend_countdown-- <= 0)
+ apm_do_suspend();
+
if (!sc->bios_busy)
apm_processevent();
@@ -826,7 +893,7 @@
if (apm_op_inprog == 0) {
apm_op_inprog++;
if (apm_record_event(sc, apm_event)) {
- apm_suspend(PMST_SUSPEND);
+ apm_do_suspend();
}
}
return; /* XXX skip the rest */
@@ -835,12 +902,12 @@
if (apm_op_inprog == 0) {
apm_op_inprog++;
if (apm_record_event(sc, apm_event)) {
- apm_suspend(PMST_SUSPEND);
+ apm_do_suspend();
}
}
return; /* XXX skip the rest */
OPMEV_DEBUGMESSAGE(PMEV_CRITSUSPEND);
- apm_suspend(PMST_SUSPEND);
+ apm_do_suspend();
break;
OPMEV_DEBUGMESSAGE(PMEV_NORMRESUME);
apm_record_event(sc, apm_event);
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message