NetBSD Problem Report #34961

From anthony.mallet@useless-ficus.net  Wed Nov  1 13:42:42 2006
Return-Path: <anthony.mallet@useless-ficus.net>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by narn.NetBSD.org (Postfix) with ESMTP id A9EC763B8CA
	for <gnats-bugs@gnats.netbsd.org>; Wed,  1 Nov 2006 13:42:42 +0000 (UTC)
Message-Id: <1162384955.23540@citrus>
Date: Wed, 1 Nov 2006 13:42:35 +0100
From: "\"\" <Anthony Mallet" <anthony.mallet@useless-ficus.net>
Reply-To:
To: "gnats bugs" <gnats-bugs@NetBSD.org>
Subject: sysutils/gkrellm support for acpibat
X-Send-Pr-Version: gtk-send-pr 0.4.7 
X-GNATS-Notify:

>Number:         34961
>Category:       pkg
>Synopsis:       sysutils/gkrellm support for acpibat
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pkg-manager
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Nov 01 13:45:00 +0000 2006
>Last-Modified:  Mon Nov 01 00:14:22 +0000 2010
>Originator:     "\"\" <Anthony Mallet" <anthony.mallet@useless-ficus.net>
>Release:        NetBSD 4.99.3 i386
>Organization:
>Environment:


System: NetBSD 4.99.3 (CITRUS) #4: Sat Oct 21 03:38:26 CEST 2006
	troot@citrus:/usr/obj/sys/arch/i386/compile/CITRUS



>Description:


I added support for acpibat in gkrellm battery monitor, for those laptops that don't have
apm support. This is implemented via envsys(4) API.

The gkrellm_sys_battery_init() function first look if apm support is present, and falls back to
 envsys(4) if /dev/apm cannot be opened.

Patches are provided and diffed against 2.2.10 *patched* version that I provided in
PR#34957. If you name my patch files patch-b{a,b,c} this should work :p.

Cheers.



>How-To-Repeat:





>Fix:


--- patch-ba begins here ---
$NetBSD$

--- src/sysdeps/openbsd.c~	2006-03-30 00:23:37.000000000 +0200
+++ src/sysdeps/openbsd.c	2006-10-31 22:12:03.000000000 +0100
@@ -199,3 +199,55 @@
 	return FALSE;
 	}

+
+/* ===================================================================== */
+/* Battery monitor interface */
+#include <sys/ioctl.h>
+
+#if defined(__i386__) || defined(__powerpc__)
+
+#include <machine/apmvar.h>
+#define	APMDEV		"/dev/apm"
+
+void
+gkrellm_sys_battery_read_data(void)
+	{
+	int			f, r;
+	struct apm_power_info info;
+	gboolean    available, on_line, charging;
+	gint        percent, time_left;
+
+	if ((f = open(APMDEV, O_RDONLY)) == -1) return;
+	memset(&info, 0, sizeof(info));
+	r = ioctl(f, APM_IOC_GETPOWER, &info);
+	close(f);
+	if (r == -1) return;
+
+	available = (info.battery_state != APM_BATT_UNKNOWN);
+	on_line = (info.ac_state == APM_AC_ON) ? TRUE : FALSE;
+	charging = (info.battery_state == APM_BATT_CHARGING) ? TRUE : FALSE;
+	percent = info.battery_life;
+	time_left = info.minutes_left;
+	gkrellm_battery_assign_data(0, available, on_line, charging,
+				percent, time_left);
+	}
+
+gboolean
+gkrellm_sys_battery_init()
+	{
+	return TRUE;
+	}
+
+#else
+
+void
+gkrellm_sys_battery_read_data(void)
+	{
+	}
+
+gboolean
+gkrellm_sys_battery_init()
+	{
+	return FALSE;
+	}
+#endif
--- patch-ba ends here ---
--- patch-bb begins here ---
$NetBSD$

--- src/sysdeps/bsd-net-open.c~	2006-11-01 12:06:53.000000000 +0100
+++ src/sysdeps/bsd-net-open.c	2006-11-01 12:07:01.000000000 +0100
@@ -98,57 +98,5 @@
 gboolean
 gkrellm_sys_inet_init(void)
 	{
 	return TRUE;
 	}
-
-/* ===================================================================== */
-/* Battery monitor interface */
-#include <sys/ioctl.h>
-
-#if defined(__i386__) || defined(__powerpc__)
-
-#include <machine/apmvar.h>
-#define	APMDEV		"/dev/apm"
-
-void
-gkrellm_sys_battery_read_data(void)
-	{
-	int			f, r;
-	struct apm_power_info info;
-	gboolean    available, on_line, charging;
-	gint        percent, time_left;
-
-	if ((f = open(APMDEV, O_RDONLY)) == -1) return;
-	memset(&info, 0, sizeof(info));
-	r = ioctl(f, APM_IOC_GETPOWER, &info);
-	close(f);
-	if (r == -1) return;
-
-	available = (info.battery_state != APM_BATT_UNKNOWN);
-	on_line = (info.ac_state == APM_AC_ON) ? TRUE : FALSE;
-	charging = (info.battery_state == APM_BATT_CHARGING) ? TRUE : FALSE;
-	percent = info.battery_life;
-	time_left = info.minutes_left;
-	gkrellm_battery_assign_data(0, available, on_line, charging,
-				percent, time_left);
-	}
-
-gboolean
-gkrellm_sys_battery_init()
-	{
-	return TRUE;
-	}
-
-#else
-
-void
-gkrellm_sys_battery_read_data(void)
-	{
-	}
-
-gboolean
-gkrellm_sys_battery_init()
-	{
-	return FALSE;
-	}
-#endif
--- patch-bb ends here ---
--- patch-bc begins here ---
$NetBSD$

--- src/sysdeps/netbsd.c~	2006-03-30 00:23:37.000000000 +0200
+++ src/sysdeps/netbsd.c	2006-10-31 22:17:41.000000000 +0100
@@ -336,3 +336,226 @@
    return found_sensors;
 }

+
+
+/* ===================================================================== */
+/* Battery monitor interface */
+
+#if defined(__i386__) || defined(__powerpc__)
+# include <sys/ioctl.h>
+# include <machine/apmvar.h>
+
+# define	APMDEV		"/dev/apm"
+#endif
+
+static int battery_use_apm = 1;
+
+/* battery data, index by [battery number] */
+static struct battery_acpi_data {
+  gboolean available;	int available_index;
+  gboolean on_line;	int on_line_index;
+  gboolean charging;	int charging_index;
+  gint full_cap;	int full_cap_index;
+  gint cap;		int cap_index;
+  gint discharge_rate;	int discharge_rate_index;
+  gint charge_rate;	int charge_rate_index;
+} *battery_acpi_data;
+static int battery_acpi_data_items;
+
+static int
+gkrellm_battery_data_alloc(int bat)
+{
+  if (bat + 1 > battery_acpi_data_items)
+    battery_acpi_data_items = bat + 1;
+
+  battery_acpi_data = realloc(battery_acpi_data,
+			      battery_acpi_data_items*
+			      sizeof(*battery_acpi_data));
+  return battery_acpi_data?1:0;
+}
+
+void
+gkrellm_sys_battery_read_data(void)
+{
+  int i;
+  int fd;			/* file desc. for /dev/sysmon or /dev/apm */
+  envsys_tre_data_t data;	/* sensor data */
+  int time_left;
+
+  if (battery_use_apm) {
+#if defined(__i386__) || defined(__powerpc__)
+    int			r;
+    struct apm_power_info apminfo;
+    gboolean available, on_line, charging;
+    gint percent, time_left;
+
+    if ((fd = open(APMDEV, O_RDONLY)) == -1) return;
+    memset(&apminfo, 0, sizeof(apminfo));
+    r = ioctl(fd, APM_IOC_GETPOWER, &apminfo);
+    close(fd);
+    if (r == -1) return;
+
+    available = (apminfo.battery_state != APM_BATT_UNKNOWN);
+    on_line = (apminfo.ac_state == APM_AC_ON) ? TRUE : FALSE;
+    charging = (apminfo.battery_state == APM_BATT_CHARGING) ? TRUE : FALSE;
+    percent = apminfo.battery_life;
+    time_left = apminfo.minutes_left;
+    gkrellm_battery_assign_data(0, available, on_line, charging,
+				percent, time_left);
+#else
+    return;
+#endif
+  }
+
+   fd = open(SENSORS_DIR, O_RDONLY);
+   if (fd < 0) return;
+
+   data.sensor = battery_acpi_data[0].on_line_index;
+   if (ioctl(fd, ENVSYS_GTREDATA, &data) < 0) return;
+   if (!(data.validflags & ENVSYS_FVALID)) return;
+   battery_acpi_data[0].on_line = data.cur.data_us ? TRUE:FALSE;
+
+   /* iterate through available batteries */
+   for(i=0; i<battery_acpi_data_items; i++) {
+#define read_sensor(x)							\
+     do {								\
+       data.sensor = battery_acpi_data[i].x ## _index;			\
+       if (ioctl(fd, ENVSYS_GTREDATA, &data) < 0) continue;		\
+       if (!(data.validflags & ENVSYS_FCURVALID))			\
+	 battery_acpi_data[i].x = -1;					\
+       else								\
+	 battery_acpi_data[i].x = data.cur.data_s;			\
+     } while(0)
+
+     read_sensor(available);
+     read_sensor(charging);
+     read_sensor(full_cap);
+     read_sensor(cap);
+     read_sensor(discharge_rate);
+     read_sensor(charge_rate);
+#undef read_sensor
+
+     if (battery_acpi_data[i].discharge_rate > 0)
+       time_left =
+	 battery_acpi_data[i].cap * 60 / battery_acpi_data[i].discharge_rate;
+     else if (battery_acpi_data[i].charge_rate > 0)
+       time_left =
+	 (battery_acpi_data[i].full_cap - battery_acpi_data[i].cap) * 60 /
+	 battery_acpi_data[i].charge_rate;
+     else
+       time_left = -1;
+
+     if (battery_acpi_data[i].available) {
+       gkrellm_battery_assign_data(i,
+				   battery_acpi_data[i].available,
+				   battery_acpi_data[0].on_line,
+				   battery_acpi_data[i].charging,
+
+				   /* percent */
+				   battery_acpi_data[i].cap * 100 /
+				   battery_acpi_data[i].full_cap,
+
+				   /* time left (minutes) */
+				   time_left);
+     } else
+       gkrellm_battery_assign_data(i, 0, 0, 0, -1, -1);
+   }
+
+   close(fd);
+}
+
+gboolean
+gkrellm_sys_battery_init()
+{
+   int fd;			/* file desc. for /dev/sysmon or /dev/apm */
+   envsys_basic_info_t info;	/* sensor misc. info */
+   gboolean found_sensors = FALSE;
+   char fake[2];
+   int r, bat;
+
+   /* --- check APM first --- */
+
+#if defined(__i386__) || defined(__powerpc__)
+   do {
+     struct apm_power_info info;
+
+     if ((fd = open(APMDEV, O_RDONLY)) == -1) break;
+     r = ioctl(fd, APM_IOC_GETPOWER, &info);
+     close(fd);
+     if (r != -1) {
+       battery_use_apm = 1;
+       return TRUE;
+     }
+   } while(0);
+#endif
+
+   /* --- check for some envsys(4) acpi battery --- */
+
+   battery_use_apm = 0;
+   battery_acpi_data_items = 0;
+   battery_acpi_data = NULL; /* this is never freed */
+
+   fd = open(SENSORS_DIR, O_RDONLY);
+   if (fd < 0) return FALSE;
+
+   /* iterate through available sensors */
+   for(info.sensor=0; ; info.sensor++) {
+      /* stop if we can't ioctl() */
+      if (ioctl(fd, ENVSYS_GTREINFO, &info) < 0) break;
+      /* stop if that sensor is not valid */
+      if (!(info.validflags & ENVSYS_FVALID)) break;
+
+      do {
+	if (info.units == ENVSYS_INDICATOR &&
+	    sscanf(info.desc, "acpibat%d presen%1[t]", &bat, fake) == 2) {
+	  if (!gkrellm_battery_data_alloc(bat)) return FALSE;
+	  battery_acpi_data[bat].available_index = info.sensor;
+	  found_sensors = TRUE;
+
+	} else if (info.units == ENVSYS_INDICATOR &&
+		   sscanf(info.desc, "acpiacad%*d connecte%1[d]", fake) == 1) {
+	  if (!gkrellm_battery_data_alloc(0)) return FALSE;
+	  battery_acpi_data[0].on_line_index = info.sensor;
+
+	} else if (info.units == ENVSYS_INDICATOR &&
+		   sscanf(info.desc,
+			  "acpibat%d chargin%1[g]", &bat, fake) == 2) {
+	  if (!gkrellm_battery_data_alloc(bat)) return FALSE;
+	  battery_acpi_data[bat].charging_index = info.sensor;
+	  found_sensors = TRUE;
+
+	} else if (info.units == ENVSYS_SAMPHOUR &&
+		   sscanf(info.desc,
+			  "acpibat%d design ca%1[p]", &bat, fake) == 2) {
+	  if (!gkrellm_battery_data_alloc(bat)) return FALSE;
+	  battery_acpi_data[bat].full_cap_index = info.sensor;
+	  found_sensors = TRUE;
+
+	} else if (info.units == ENVSYS_SAMPHOUR &&
+		   sscanf(info.desc,
+			  "acpibat%d charg%1[e]", &bat, fake) == 2) {
+	  if (!gkrellm_battery_data_alloc(bat)) return FALSE;
+	  battery_acpi_data[bat].cap_index = info.sensor;
+	  found_sensors = TRUE;
+
+	} else if (info.units == ENVSYS_SAMPS &&
+		   sscanf(info.desc,
+			  "acpibat%d discharge rat%1[e]", &bat, fake) == 2) {
+	  if (!gkrellm_battery_data_alloc(bat)) return FALSE;
+	  battery_acpi_data[bat].discharge_rate_index = info.sensor;
+	  found_sensors = TRUE;
+
+	} else if (info.units == ENVSYS_SAMPS &&
+		   sscanf(info.desc,
+			  "acpibat%d charge rat%1[e]", &bat, fake) == 2) {
+	  if (!gkrellm_battery_data_alloc(bat)) return FALSE;
+	  battery_acpi_data[bat].charge_rate_index = info.sensor;
+	  found_sensors = TRUE;
+	}
+      } while(0);
+   }
+
+   close(fd);
+
+   return found_sensors;
+}
--- patch-bc ends here ---



>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: pkg-manager->cube
Responsible-Changed-By: reed@netbsd.org
Responsible-Changed-When: Fri, 03 Nov 2006 15:36:57 +0000
Responsible-Changed-Why:
Assigned to maintainer.


Responsible-Changed-From-To: cube->pkg-manager
Responsible-Changed-By: wiz@NetBSD.org
Responsible-Changed-When: Mon, 01 Nov 2010 00:14:22 +0000
Responsible-Changed-Why:
back to role account.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.