Subject: apmd and the APM_POWER_CHANGE event
To: None <port-i386@netbsd.org>
From: Chuck Cranor <chuck@xxx.research.att.com>
List: port-i386
Date: 01/24/2001 19:32:59
hi-

    i have discovered another thinkpad T21 apm quirk in 1.5 (and 
current).  when the apmd program receives an APM_POWER_CHANGE event 
it always runs either /etc/apm/battery or /etc/apm/suspend.

    turns out that my APM BIOS posts periodic APM_POWER_CHANGE
events while the battery is charging or discharging (even if a/c
state does not change).   so if i unplug my system it runs 
/etc/apm/battery every time one of these events is posted (even 
though it really only needs to run it once).   you can see this if 
you put something like:

	logger -p daemon.alert 'using battery power settings' `date`

in /etc/apm/battery.

    the following patch causes apmd to do a bit more checking
before running /etc/apm/{battery,line}.   i'll commit it shortly.

    with this patch (and the previous apm and npx patches) applied
i find that apm/apmd are now working well under 1.5 on the thinkpad T21.


chuck


Index: apmd.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/apmd/apmd.c,v
retrieving revision 1.16
diff -c -r1.16 apmd.c
*** apmd.c	2001/01/11 01:35:53	1.16
--- apmd.c	2001/01/25 00:25:35
***************
*** 314,319 ****
--- 314,320 ----
      fd_set selcopy;
      struct apm_event_info apmevent;
      int suspends, standbys, resumes;
+     int ac_is_off;
      int noacsleep = 0;
      int lowbattsleep = 0;
      mode_t mode = 0660;
***************
*** 414,419 ****
--- 415,421 ----
  	struct apm_power_info pinfo;
  	power_status(ctl_fd, 1, &pinfo);
  	do_ac_state(pinfo.ac_state);
+ 	ac_is_off = (pinfo.ac_state == APM_AC_OFF);
      }
  
      (void) signal(SIGTERM, sigexit);
***************
*** 484,490 ****
  		{
  		    struct apm_power_info pinfo;
  		    power_status(ctl_fd, 0, &pinfo);
! 		    do_ac_state(pinfo.ac_state);
  		    break;
  		}
  		default:
--- 486,496 ----
  		{
  		    struct apm_power_info pinfo;
  		    power_status(ctl_fd, 0, &pinfo);
! 		    /* power status can change without ac status changing */
! 		    if (ac_is_off != (pinfo.ac_state == APM_AC_OFF)) {
! 		    	do_ac_state(pinfo.ac_state);
! 			ac_is_off = (pinfo.ac_state == APM_AC_OFF);
! 		    }
  		    break;
  		}
  		default:
-- 
Chuck Cranor                            http://www.research.att.com/info/chuck
Senior Technical Staff Member		chuck@research.att.com
Internet and Networking Systems Research Lab
AT&T Labs-Research, Florham Park, NJ