Subject: port-i386/10545: multiple battery support in APM
To: None <gnats-bugs@gnats.netbsd.org>
From: None <itojun@itojun.org>
List: netbsd-bugs
Date: 07/08/2000 20:26:13
>Number: 10545
>Category: port-i386
>Synopsis: multiple battery support in APM
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: port-i386-maintainer
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sat Jul 08 20:27:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: Jun-ichiro itojun Hagino
>Release: latest current
>Organization:
itojun.org
>Environment:
System: NetBSD starfruit.itojun.org 1.5B NetBSD 1.5B (STARFRUIT) #40: Sun Jul 9 11:49:28 JST 2000 itojun@starfruit.itojun.org:/usr/home/itojun/NetBSD/src/sys/arch/i386/compile/STARFRUIT i386
>Description:
the attached patch tries to add multiple battery support into APM code.
at this moment we can only be able to see # of batteries on the system.
once we define some ioctl, we can query status for non-default
batteries. could someone finish it?
>How-To-Repeat:
>Fix:
Index: sys/arch/i386/include/apmvar.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/include/apmvar.h,v
retrieving revision 1.9
diff -c -r1.9 apmvar.h
*** apmvar.h 1999/08/17 19:05:53 1.9
--- apmvar.h 2000/07/09 03:23:06
***************
*** 280,286 ****
u_char battery_life;
u_char spare1;
u_int minutes_left; /* estimate */
! u_int spare2[6];
};
struct apm_ctl {
--- 280,288 ----
u_char battery_life;
u_char spare1;
u_int minutes_left; /* estimate */
! u_int nbattery;
! u_int batteryid;
! u_int spare2[4];
};
struct apm_ctl {
Index: sys/arch/i386/i386/apm.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/i386/apm.c,v
retrieving revision 1.50
diff -c -r1.50 apm.c
*** apm.c 2000/06/04 22:36:27 1.50
--- apm.c 2000/07/09 03:23:09
***************
*** 145,151 ****
#endif
static void apm_event_handle __P((struct apm_softc *, struct bioscallregs *));
static int apm_get_event __P((struct bioscallregs *));
! static int apm_get_powstat __P((struct bioscallregs *));
#if 0
static void apm_get_powstate __P((u_int));
#endif
--- 145,151 ----
#endif
static void apm_event_handle __P((struct apm_softc *, struct bioscallregs *));
static int apm_get_event __P((struct bioscallregs *));
! static int apm_get_powstat __P((struct bioscallregs *, u_int));
#if 0
static void apm_get_powstate __P((u_int));
#endif
***************
*** 160,166 ****
static void apm_powmgt_enable __P((int));
static void apm_powmgt_engage __P((int, u_int));
static int apm_record_event __P((struct apm_softc *, u_int));
! static void apm_get_capabilities __P((void));
static void apm_set_ver __P((struct apm_softc *));
static void apm_standby __P((struct apm_softc *));
static const char *apm_strerror __P((int));
--- 160,166 ----
static void apm_powmgt_enable __P((int));
static void apm_powmgt_engage __P((int, u_int));
static int apm_record_event __P((struct apm_softc *, u_int));
! static void apm_get_capabilities __P((struct bioscallregs *));
static void apm_set_ver __P((struct apm_softc *));
static void apm_standby __P((struct apm_softc *));
static const char *apm_strerror __P((int));
***************
*** 545,551 ****
case APM_POWER_CHANGE:
DPRINTF(APMDEBUG_EVENTS, ("apmev: power status change\n"));
! error = apm_get_powstat(&nregs);
#ifdef APM_POWER_PRINT
/* only print if nobody is catching events. */
if (error == 0 &&
--- 545,551 ----
case APM_POWER_CHANGE:
DPRINTF(APMDEBUG_EVENTS, ("apmev: power status change\n"));
! error = apm_get_powstat(&nregs, 0);
#ifdef APM_POWER_PRINT
/* only print if nobody is catching events. */
if (error == 0 &&
***************
*** 592,599 ****
if (apm_minver < 2) {
DPRINTF(APMDEBUG_EVENTS, ("apm: unexpected event\n"));
} else {
! apm_get_capabilities();
! apm_get_powstat(&nregs); /* XXX */
}
break;
--- 592,599 ----
if (apm_minver < 2) {
DPRINTF(APMDEBUG_EVENTS, ("apm: unexpected event\n"));
} else {
! apm_get_capabilities(&nregs);
! apm_get_powstat(&nregs, 0); /* XXX */
}
break;
***************
*** 761,794 ****
/* V1.2 */
static void
! apm_get_capabilities()
{
- struct bioscallregs regs;
! regs.BX = APM_DEV_APM_BIOS;
! if (apmcall(APM_GET_CAPABILITIES, ®s) != 0) {
! apm_perror("get capabilities", ®s);
return;
}
#ifdef APMDEBUG
/* print out stats */
! printf("apm: %d batteries", APM_NBATTERIES(®s));
! if (regs.CX & APM_GLOBAL_STANDBY)
printf(", global standby");
! if (regs.CX & APM_GLOBAL_SUSPEND)
printf(", global suspend");
! if (regs.CX & APM_RTIMER_STANDBY)
printf(", rtimer standby");
! if (regs.CX & APM_RTIMER_SUSPEND)
printf(", rtimer suspend");
! if (regs.CX & APM_IRRING_STANDBY)
printf(", internal standby");
! if (regs.CX & APM_IRRING_SUSPEND)
printf(", internal suspend");
! if (regs.CX & APM_PCRING_STANDBY)
printf(", pccard standby");
! if (regs.CX & APM_PCRING_SUSPEND)
printf(", pccard suspend");
printf("\n");
#endif
--- 761,794 ----
/* V1.2 */
static void
! apm_get_capabilities(regs)
! struct bioscallregs *regs;
{
! regs->BX = APM_DEV_APM_BIOS;
! if (apmcall(APM_GET_CAPABILITIES, regs) != 0) {
! apm_perror("get capabilities", regs);
return;
}
#ifdef APMDEBUG
/* print out stats */
! printf("apm: %d batteries", APM_NBATTERIES(regs));
! if (regs->CX & APM_GLOBAL_STANDBY)
printf(", global standby");
! if (regs->CX & APM_GLOBAL_SUSPEND)
printf(", global suspend");
! if (regs->CX & APM_RTIMER_STANDBY)
printf(", rtimer standby");
! if (regs->CX & APM_RTIMER_SUSPEND)
printf(", rtimer suspend");
! if (regs->CX & APM_IRRING_STANDBY)
printf(", internal standby");
! if (regs->CX & APM_IRRING_SUSPEND)
printf(", internal suspend");
! if (regs->CX & APM_PCRING_STANDBY)
printf(", pccard standby");
! if (regs->CX & APM_PCRING_SUSPEND)
printf(", pccard suspend");
printf("\n");
#endif
***************
*** 842,852 ****
}
static int
! apm_get_powstat(regs)
struct bioscallregs *regs;
{
! regs->BX = APM_DEV_ALLDEVS;
return apmcall(APM_POWER_STATUS, regs);
}
--- 842,856 ----
}
static int
! apm_get_powstat(regs, batteryid)
struct bioscallregs *regs;
+ u_int batteryid;
{
! if (batteryid == 0)
! regs->BX = APM_DEV_ALLDEVS;
! else
! regs->BX = APM_DEV_BATTERY(batteryid);
return apmcall(APM_POWER_STATUS, regs);
}
***************
*** 1267,1273 ****
apm_set_ver(apmsc); /* prints version info */
printf("\n");
if (apm_minver >= 2)
! apm_get_capabilities();
/*
* enable power management if it's disabled.
--- 1271,1277 ----
apm_set_ver(apmsc); /* prints version info */
printf("\n");
if (apm_minver >= 2)
! apm_get_capabilities(®s);
/*
* enable power management if it's disabled.
***************
*** 1295,1301 ****
apm_powmgt_engage(1, APM_DEV_PCMCIA(APM_DEV_ALLUNITS));
#endif
memset(®s, 0, sizeof(regs));
! error = apm_get_powstat(®s);
if (error == 0) {
#ifdef APM_POWER_PRINT
apm_power_print(apmsc, ®s);
--- 1299,1305 ----
apm_powmgt_engage(1, APM_DEV_PCMCIA(APM_DEV_ALLUNITS));
#endif
memset(®s, 0, sizeof(regs));
! error = apm_get_powstat(®s, 0);
if (error == 0) {
#ifdef APM_POWER_PRINT
apm_power_print(apmsc, ®s);
***************
*** 1476,1481 ****
--- 1480,1486 ----
#if 0
struct apm_ctl *actl;
#endif
+ u_int batteryid, nbattery;
int i, error = 0;
APM_LOCK(sc);
***************
*** 1527,1539 ****
case APM_IOC_GETPOWER:
powerp = (struct apm_power_info *)data;
! if (apm_get_powstat(®s)) {
apm_perror("ioctl get power status", ®s);
error = EIO;
break;
}
memset(powerp, 0, sizeof(*powerp));
if (APM_BATT_LIFE(®s) != APM_BATT_LIFE_UNKNOWN)
powerp->battery_life = APM_BATT_LIFE(®s);
powerp->ac_state = APM_AC_STATE(®s);
--- 1532,1561 ----
case APM_IOC_GETPOWER:
powerp = (struct apm_power_info *)data;
! batteryid = 0; /* need a way to pass it from the userland */
! if (apm_minver >= 2) {
! apm_get_capabilities(®s);
! if (batteryid > APM_NBATTERIES(®s)) {
! error = EIO;
! break;
! }
! nbattery = APM_NBATTERIES(®s);
! } else {
! if (batteryid > 0) {
! error = EIO;
! break;
! }
! nbattery = 0;
! }
! if (apm_get_powstat(®s, batteryid)) {
apm_perror("ioctl get power status", ®s);
error = EIO;
break;
}
memset(powerp, 0, sizeof(*powerp));
+ powerp->batteryid = batteryid;
+ powerp->nbattery = nbattery;
if (APM_BATT_LIFE(®s) != APM_BATT_LIFE_UNKNOWN)
powerp->battery_life = APM_BATT_LIFE(®s);
powerp->ac_state = APM_AC_STATE(®s);
Index: usr.sbin/apm/apm.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/apm/apm.c,v
retrieving revision 1.8
diff -c -r1.8 apm.c
*** apm.c 1999/01/15 00:29:02 1.8
--- apm.c 2000/07/09 03:23:10
***************
*** 298,303 ****
--- 298,307 ----
printf("A/C adapter state: %s\n", ac_state(reply.batterystate.ac_state));
if (dostatus)
printf("Power management enabled\n");
+ if (reply.batterystate.nbattery) {
+ printf("Number of batteries: %u\n",
+ reply.batterystate.nbattery);
+ }
} else {
if (dobstate)
printf("%d\n", reply.batterystate.battery_state);
>Release-Note:
>Audit-Trail:
>Unformatted: