Module Name:    src
Committed By:   pgoyette
Date:           Sun Mar 28 13:11:23 UTC 2010

Modified Files:
        src/sys/dev/acpi: acpi_apm.c

Log Message:
Update acpiapm_get_powstat() to adjust for the recent changes to
acpi_bat(4).  (The warn_cap and low_cap sensors were removed, and the
values are now stored as the alarm limits of the charge sensor.)


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/acpi/acpi_apm.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/acpi/acpi_apm.c
diff -u src/sys/dev/acpi/acpi_apm.c:1.16 src/sys/dev/acpi/acpi_apm.c:1.17
--- src/sys/dev/acpi/acpi_apm.c:1.16	Wed Mar 24 01:45:37 2010
+++ src/sys/dev/acpi/acpi_apm.c	Sun Mar 28 13:11:23 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: acpi_apm.c,v 1.16 2010/03/24 01:45:37 pgoyette Exp $	*/
+/*	$NetBSD: acpi_apm.c,v 1.17 2010/03/28 13:11:23 pgoyette Exp $	*/
 
 /*-
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -35,12 +35,16 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_apm.c,v 1.16 2010/03/24 01:45:37 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_apm.c,v 1.17 2010/03/28 13:11:23 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/device.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
+#include <sys/queue.h>
+#include <sys/envsys.h>
+
+#include <dev/sysmon/sysmonvar.h>
 
 #include <dev/acpi/acpivar.h>
 #include <dev/apm/apmvar.h>
@@ -49,6 +53,8 @@
 static void	acpiapm_enable(void *, int);
 static int	acpiapm_set_powstate(void *, u_int, u_int);
 static int	acpiapm_get_powstat(void *, u_int, struct apm_power_info *);
+static bool	apm_per_sensor(const struct sysmon_envsys *,
+			       const envsys_data_t *, void *);
 static int	acpiapm_get_event(void *, u_int *, u_int *);
 static void	acpiapm_cpu_busy(void *);
 static void	acpiapm_cpu_idle(void *);
@@ -253,6 +259,69 @@
 	return 0;
 }
 
+struct apm_sensor_info {
+	struct apm_power_info *pinfo;
+	int present;
+	int lastcap, descap, cap, warncap, lowcap, discharge;
+	int lastcap_valid, cap_valid, discharge_valid;
+};
+
+static bool
+apm_per_sensor(const struct sysmon_envsys *sme, const envsys_data_t *edata,
+	       void *arg)
+{
+	struct apm_sensor_info *info = (struct apm_sensor_info *)arg;
+	int data;
+
+	if (sme->sme_class != SME_CLASS_ACADAPTER &&
+	    sme->sme_class != SME_CLASS_BATTERY)
+		return false;
+
+	if (edata->state == ENVSYS_SINVALID)
+		return true;
+
+	data = edata->value_cur;
+
+	DPRINTF(("%s (%s) %d\n", sme->sme_name, edata->desc, data));
+
+	if (strstr(edata->desc, "connected")) {
+		info->pinfo->ac_state = data ? APM_AC_ON : APM_AC_OFF;
+	}
+	else if (strstr(edata->desc, "present") && data != 0)
+		info->present++;
+	else if (strstr(edata->desc, "charging")) {
+		if (data)
+			info->pinfo->battery_flags |= APM_BATT_FLAG_CHARGING;
+		else
+			info->pinfo->battery_flags &= ~APM_BATT_FLAG_CHARGING;
+		}
+	else if (strstr(edata->desc, "last full cap")) {
+		info->lastcap += data / 1000;
+		info->lastcap_valid = 1;
+	}
+	else if (strstr(edata->desc, "design cap"))
+		info->descap = data / 1000;
+	else if (strstr(edata->desc, "charge") &&
+	    strstr(edata->desc, "charge rate") == NULL &&
+	    strstr(edata->desc, "charge state") == NULL) {
+
+		/* Update cumulative capacity */
+		info->cap += data / 1000;
+
+		/* get warning- & critical-capacity values */
+		info->warncap = edata->limits.sel_warnmin / 1000;
+		info->lowcap = edata->limits.sel_critmin / 1000;
+
+		info->cap_valid = 1;
+		info->pinfo->nbattery++;
+	}
+	else if (strstr(edata->desc, "discharge rate")) {
+		info->discharge += data / 1000;
+		info->discharge_valid = 1;
+	}
+	return true;
+}
+
 static int
 /*ARGSUSED*/
 acpiapm_get_powstat(void *opaque, u_int batteryid,
@@ -261,17 +330,20 @@
 #define APM_BATT_FLAG_WATERMARK_MASK (APM_BATT_FLAG_CRITICAL |		      \
 				      APM_BATT_FLAG_LOW |		      \
 				      APM_BATT_FLAG_HIGH)
-	int i, curcap, lowcap, warncap, cap, descap, lastcap, discharge;
-	int cap_valid, lastcap_valid, discharge_valid, present;
-	envsys_tre_data_t etds;
-	envsys_basic_info_t ebis;
+	struct apm_sensor_info info;
 
 	/* Denote most variables as unitialized. */
-	curcap = lowcap = warncap = descap = -1;
+	info.lowcap = info.warncap = info.descap = -1;
 
-	/* Prepare to aggregate these two variables over all batteries. */
-	cap = lastcap = discharge = 0;
-	cap_valid = lastcap_valid = discharge_valid = present = 0;
+	/*
+	 * Prepare to aggregate capacity, charge, and discharge over all
+	 * batteries.
+	 */
+	info.cap = info.lastcap = info.discharge = 0;
+	info.cap_valid = info.lastcap_valid = info.discharge_valid = 0;
+	info.present = 0;
+
+	info.pinfo = pinfo;
 
 	(void)memset(pinfo, 0, sizeof(*pinfo));
 	pinfo->ac_state = APM_AC_UNKNOWN;
@@ -283,82 +355,31 @@
 	pinfo->battery_state = APM_BATT_UNKNOWN; /* ignored */
 	pinfo->battery_life = APM_BATT_LIFE_UNKNOWN;
 
-	sysmonopen_envsys(0, 0, 0, &lwp0);
-
-	for (i = 0;; i++) {
-		const char *desc;
-		int data;
-		int flags;
-
-		ebis.sensor = i;
-		if (sysmonioctl_envsys(0, ENVSYS_GTREINFO, (void *)&ebis, 0,
-		    NULL) || (ebis.validflags & ENVSYS_FVALID) == 0)
-			break;
-		etds.sensor = i;
-		if (sysmonioctl_envsys(0, ENVSYS_GTREDATA, (void *)&etds, 0,
-		    NULL))
-			continue;
-		desc = ebis.desc;
-		flags = etds.validflags;
-		data = etds.cur.data_s;
-
-		DPRINTF(("%d %s %d %d\n", i, desc, data, flags));
-		if ((flags & ENVSYS_FCURVALID) == 0)
-			continue;
-		if (strstr(desc, " connected")) {
-			pinfo->ac_state = data ? APM_AC_ON : APM_AC_OFF;
-		} else if (strstr(desc, " present") && data != 0)
-			present++;
-		else if (strstr(desc, " charging") && data)
-			pinfo->battery_flags |= APM_BATT_FLAG_CHARGING;
-		else if (strstr(desc, " charging") && !data)
-			pinfo->battery_flags &= ~APM_BATT_FLAG_CHARGING;
-		else if (strstr(desc, " warn cap"))
-			warncap = data / 1000;
-		else if (strstr(desc, " low cap"))
-			lowcap = data / 1000;
-		else if (strstr(desc, " last full cap")) {
-			lastcap += data / 1000;
-			lastcap_valid = 1;
-		}
-		else if (strstr(desc, " design cap"))
-			descap = data / 1000;
-		else if (strstr(desc, " charge") &&
-		    strstr(desc, " charge rate") == NULL &&
-		    strstr(desc, " charge state") == NULL) {
-			cap += data / 1000;
-			cap_valid = 1;
-			pinfo->nbattery++;
-		}
-		else if (strstr(desc, " discharge rate")) {
-			discharge += data / 1000;
-			discharge_valid = 1;
-		}
-	}
-	sysmonclose_envsys(0, 0, 0, &lwp0);
+	sysmon_envsys_foreach_sensor(apm_per_sensor, (void *)&info, true);
 
-	if (present == 0)
+	if (info.present == 0)
 		pinfo->battery_flags |= APM_BATT_FLAG_NO_SYSTEM_BATTERY;
 
-	if (cap_valid > 0)  {
-		if (warncap != -1 && cap < warncap)
+	if (info.cap_valid > 0)  {
+		if (info.warncap != -1 && info.cap < info.warncap)
 			pinfo->battery_flags |= APM_BATT_FLAG_CRITICAL;
-		else if (lowcap != -1) {
-			if (cap < lowcap)
+		else if (info.lowcap != -1) {
+			if (info.cap < info.lowcap)
 				pinfo->battery_flags |= APM_BATT_FLAG_LOW;
 			else
 				pinfo->battery_flags |= APM_BATT_FLAG_HIGH;
 		}
-		if (lastcap_valid > 0 && lastcap != 0)
-			pinfo->battery_life = 100 * cap / lastcap;
-		else if (descap != -1 && descap != 0)
-			pinfo->battery_life = 100 * cap / descap;
+		if (info.lastcap_valid > 0 && info.lastcap != 0)
+			pinfo->battery_life = 100 * info.cap / info.lastcap;
+		else if (info.descap != -1 && info.descap != 0)
+			pinfo->battery_life = 100 * info.cap / info.descap;
 	}
 
 	if ((pinfo->battery_flags & APM_BATT_FLAG_CHARGING) == 0) {
 		/* discharging */
-		if (discharge != -1 && cap != -1 && discharge != 0)
-			pinfo->minutes_left = 60 * cap / discharge;
+		if (info.discharge != -1 && info.discharge != 0 &&
+		    info.cap != -1)
+			pinfo->minutes_left = 60 * info.cap / info.discharge;
 	}
 	if ((pinfo->battery_flags & APM_BATT_FLAG_WATERMARK_MASK) == 0 &&
 	    (pinfo->battery_flags & APM_BATT_FLAG_NO_SYSTEM_BATTERY) == 0) {
@@ -368,8 +389,8 @@
 			pinfo->battery_flags |= APM_BATT_FLAG_LOW;
 	}
 
-	DPRINTF(("%d %d %d %d %d %d\n", cap, warncap, lowcap, lastcap, descap,
-	    discharge));
+	DPRINTF(("%d %d %d %d %d %d\n", info.cap, info.warncap, info.lowcap,
+	    info.lastcap, info.descap, info.discharge));
 	DPRINTF(("pinfo %d %d %d\n", pinfo->battery_flags,
 	    pinfo->battery_life, pinfo->battery_life));
 	return 0;

Reply via email to