I was recently toying with apmd, attempting to add the ability to
execute a command when the power status changes. This proceeded with no
problem, but I noticed on my Dell Inspiron 7000, each time I changed the
ac status (unplugged or plugged in), three POWER_STATUS_CHANGE events
were sent within a few seconds of eachother. This normally isn't a
problem... apmd just checks the battery level a few extra times. But
coupled with my modification to apmd, I really would only want 1 such
event, since the command executed might count on that (which seems
logical).
To fix this, I modified arch/i386/kernel/apm.c. The patch is attached
for version 1.9 of apm.c. Basically, each time a POWER_STATUS_CHANGE
event is received, if APM_CONFIG_IGNORE_MULTIPLE_POWER is defined
(currently I have it directly in apm.c), we check the power status,
using apm_get_power_status. If the power status is unchanged from the
status at the last such event, it is discarded, otherwise we fall
through to the old handling. Hope this is useful.
Thanks,
J.D. Smith
--
J.D. Smith |*| WORK: (607) 255-5842
Cornell University Dept. of Astronomy |*| (607) 255-6263
304 Space Sciences Bldg. |*| FAX: (607) 255-5875
Ithaca, NY 14853 |*|
--- linux/arch/i386/kernel/apm_save.c Fri Feb 26 00:54:11 1999
+++ linux/arch/i386/kernel/apm.c Sat Feb 27 20:04:16 1999
@@ -90,6 +90,10 @@
* Use CONFIG_SMP instead of __SMP__
* Ignore BOUNCES for three seconds.
* Stephen Rothwell
+ * ***: Added CONFIG_APM_IGNORE_MULTIPLE_POWER to ignore multiple
+ * POWER_STATUS_CHANGE events for which the power status
+ * doesn't change.
+ * J.D. Smith <[EMAIL PROTECTED]>
*
* APM 1.1 Reference:
*
@@ -185,12 +189,19 @@
* really only need one at a time, so just ignore any beyond the first.
* This is probably safe on most laptops.
*
+ * CONFIG_APM_IGNORE_MULTIPLE_POWER: The Dell Inspiron 7000 bios sends
+ * multiple power_status change events within a few seconds of
+ * (un)plugging the ac cord. Ignore any consecutive events for which
+ * the ac power status is unchanged. Should be safe on most laptops.
+ *
* If you are debugging the APM support for your laptop, note that code for
* all of these options is contained in this file, so you can #define or
* #undef these on the next line to avoid recompiling the whole kernel.
*
*/
+#define CONFIG_APM_IGNORE_MULTIPLE_POWER
+
/* KNOWN PROBLEM MACHINES:
*
* U: TI 4000M TravelMate: BIOS is *NOT* APM compliant
@@ -863,6 +874,12 @@
static int ignore_bounce = 0;
#endif
+#ifdef CONFIG_APM_IGNORE_MULTIPLE_POWER
+ unsigned short bx = 0xff;
+ unsigned short acls = 0xff;
+ static unsigned short save_ac_line_status = 0xff;
+#endif
+
while ((event = get_event()) != 0) {
#ifdef APM_DEBUG
if (event <= NR_APM_EVENT_NAME)
@@ -927,6 +944,14 @@
case APM_LOW_BATTERY:
case APM_POWER_STATUS_CHANGE:
+#ifdef CONFIG_APM_IGNORE_MULTIPLE_POWER
+ if (!apm_get_power_status(&bx, &acls, &acls)) {
+ acls = (bx >> 8) & 0xff;
+ if (acls == save_ac_line_status)
+ break;
+ save_ac_line_status = acls;
+ }
+#endif
case APM_CAPABILITY_CHANGE:
send_event(event, 0, NULL);
break;