| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: acpi_apm.c,v 1.15 2010/03/05 14:00:16 jruoho Exp $ */ | | 1 | /* $NetBSD: acpi_apm.c,v 1.16 2010/03/24 01:45:37 pgoyette Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2006 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2006 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Christos Zoulas and by Jared McNeill. | | 8 | * by Christos Zoulas and by Jared McNeill. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -25,27 +25,27 @@ | | | @@ -25,27 +25,27 @@ |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | * POSSIBILITY OF SUCH DAMAGE. | | 29 | * POSSIBILITY OF SUCH DAMAGE. |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | /* | | 32 | /* |
33 | * Autoconfiguration support for the Intel ACPI Component Architecture | | 33 | * Autoconfiguration support for the Intel ACPI Component Architecture |
34 | * ACPI reference implementation. | | 34 | * ACPI reference implementation. |
35 | */ | | 35 | */ |
36 | | | 36 | |
37 | #include <sys/cdefs.h> | | 37 | #include <sys/cdefs.h> |
38 | __KERNEL_RCSID(0, "$NetBSD: acpi_apm.c,v 1.15 2010/03/05 14:00:16 jruoho Exp $"); | | 38 | __KERNEL_RCSID(0, "$NetBSD: acpi_apm.c,v 1.16 2010/03/24 01:45:37 pgoyette Exp $"); |
39 | | | 39 | |
40 | #include <sys/param.h> | | 40 | #include <sys/param.h> |
41 | #include <sys/device.h> | | 41 | #include <sys/device.h> |
42 | #include <sys/sysctl.h> | | 42 | #include <sys/sysctl.h> |
43 | #include <sys/systm.h> | | 43 | #include <sys/systm.h> |
44 | | | 44 | |
45 | #include <dev/acpi/acpivar.h> | | 45 | #include <dev/acpi/acpivar.h> |
46 | #include <dev/apm/apmvar.h> | | 46 | #include <dev/apm/apmvar.h> |
47 | | | 47 | |
48 | static void acpiapm_disconnect(void *); | | 48 | static void acpiapm_disconnect(void *); |
49 | static void acpiapm_enable(void *, int); | | 49 | static void acpiapm_enable(void *, int); |
50 | static int acpiapm_set_powstate(void *, u_int, u_int); | | 50 | static int acpiapm_set_powstate(void *, u_int, u_int); |
51 | static int acpiapm_get_powstat(void *, u_int, struct apm_power_info *); | | 51 | static int acpiapm_get_powstat(void *, u_int, struct apm_power_info *); |
| @@ -252,36 +252,36 @@ acpiapm_set_powstate(void *opaque, u_int | | | @@ -252,36 +252,36 @@ acpiapm_set_powstate(void *opaque, u_int |
252 | | | 252 | |
253 | return 0; | | 253 | return 0; |
254 | } | | 254 | } |
255 | | | 255 | |
256 | static int | | 256 | static int |
257 | /*ARGSUSED*/ | | 257 | /*ARGSUSED*/ |
258 | acpiapm_get_powstat(void *opaque, u_int batteryid, | | 258 | acpiapm_get_powstat(void *opaque, u_int batteryid, |
259 | struct apm_power_info *pinfo) | | 259 | struct apm_power_info *pinfo) |
260 | { | | 260 | { |
261 | #define APM_BATT_FLAG_WATERMARK_MASK (APM_BATT_FLAG_CRITICAL | \ | | 261 | #define APM_BATT_FLAG_WATERMARK_MASK (APM_BATT_FLAG_CRITICAL | \ |
262 | APM_BATT_FLAG_LOW | \ | | 262 | APM_BATT_FLAG_LOW | \ |
263 | APM_BATT_FLAG_HIGH) | | 263 | APM_BATT_FLAG_HIGH) |
264 | int i, curcap, lowcap, warncap, cap, descap, lastcap, discharge; | | 264 | int i, curcap, lowcap, warncap, cap, descap, lastcap, discharge; |
265 | int cap_valid, lastcap_valid, discharge_valid; | | 265 | int cap_valid, lastcap_valid, discharge_valid, present; |
266 | envsys_tre_data_t etds; | | 266 | envsys_tre_data_t etds; |
267 | envsys_basic_info_t ebis; | | 267 | envsys_basic_info_t ebis; |
268 | | | 268 | |
269 | /* Denote most variables as unitialized. */ | | 269 | /* Denote most variables as unitialized. */ |
270 | curcap = lowcap = warncap = descap = -1; | | 270 | curcap = lowcap = warncap = descap = -1; |
271 | | | 271 | |
272 | /* Prepare to aggregate these two variables over all batteries. */ | | 272 | /* Prepare to aggregate these two variables over all batteries. */ |
273 | cap = lastcap = discharge = 0; | | 273 | cap = lastcap = discharge = 0; |
274 | cap_valid = lastcap_valid = discharge_valid = 0; | | 274 | cap_valid = lastcap_valid = discharge_valid = present = 0; |
275 | | | 275 | |
276 | (void)memset(pinfo, 0, sizeof(*pinfo)); | | 276 | (void)memset(pinfo, 0, sizeof(*pinfo)); |
277 | pinfo->ac_state = APM_AC_UNKNOWN; | | 277 | pinfo->ac_state = APM_AC_UNKNOWN; |
278 | pinfo->minutes_valid = 0; | | 278 | pinfo->minutes_valid = 0; |
279 | pinfo->minutes_left = 0; | | 279 | pinfo->minutes_left = 0; |
280 | pinfo->batteryid = 0; | | 280 | pinfo->batteryid = 0; |
281 | pinfo->nbattery = 0; /* to be incremented as batteries are found */ | | 281 | pinfo->nbattery = 0; /* to be incremented as batteries are found */ |
282 | pinfo->battery_flags = 0; | | 282 | pinfo->battery_flags = 0; |
283 | pinfo->battery_state = APM_BATT_UNKNOWN; /* ignored */ | | 283 | pinfo->battery_state = APM_BATT_UNKNOWN; /* ignored */ |
284 | pinfo->battery_life = APM_BATT_LIFE_UNKNOWN; | | 284 | pinfo->battery_life = APM_BATT_LIFE_UNKNOWN; |
285 | | | 285 | |
286 | sysmonopen_envsys(0, 0, 0, &lwp0); | | 286 | sysmonopen_envsys(0, 0, 0, &lwp0); |
287 | | | 287 | |
| @@ -297,28 +297,28 @@ acpiapm_get_powstat(void *opaque, u_int | | | @@ -297,28 +297,28 @@ acpiapm_get_powstat(void *opaque, u_int |
297 | etds.sensor = i; | | 297 | etds.sensor = i; |
298 | if (sysmonioctl_envsys(0, ENVSYS_GTREDATA, (void *)&etds, 0, | | 298 | if (sysmonioctl_envsys(0, ENVSYS_GTREDATA, (void *)&etds, 0, |
299 | NULL)) | | 299 | NULL)) |
300 | continue; | | 300 | continue; |
301 | desc = ebis.desc; | | 301 | desc = ebis.desc; |
302 | flags = etds.validflags; | | 302 | flags = etds.validflags; |
303 | data = etds.cur.data_s; | | 303 | data = etds.cur.data_s; |
304 | | | 304 | |
305 | DPRINTF(("%d %s %d %d\n", i, desc, data, flags)); | | 305 | DPRINTF(("%d %s %d %d\n", i, desc, data, flags)); |
306 | if ((flags & ENVSYS_FCURVALID) == 0) | | 306 | if ((flags & ENVSYS_FCURVALID) == 0) |
307 | continue; | | 307 | continue; |
308 | if (strstr(desc, " connected")) { | | 308 | if (strstr(desc, " connected")) { |
309 | pinfo->ac_state = data ? APM_AC_ON : APM_AC_OFF; | | 309 | pinfo->ac_state = data ? APM_AC_ON : APM_AC_OFF; |
310 | } else if (strstr(desc, " present") && data == 0) | | 310 | } else if (strstr(desc, " present") && data != 0) |
311 | pinfo->battery_flags |= APM_BATT_FLAG_NO_SYSTEM_BATTERY; | | 311 | present++; |
312 | else if (strstr(desc, " charging") && data) | | 312 | else if (strstr(desc, " charging") && data) |
313 | pinfo->battery_flags |= APM_BATT_FLAG_CHARGING; | | 313 | pinfo->battery_flags |= APM_BATT_FLAG_CHARGING; |
314 | else if (strstr(desc, " charging") && !data) | | 314 | else if (strstr(desc, " charging") && !data) |
315 | pinfo->battery_flags &= ~APM_BATT_FLAG_CHARGING; | | 315 | pinfo->battery_flags &= ~APM_BATT_FLAG_CHARGING; |
316 | else if (strstr(desc, " warn cap")) | | 316 | else if (strstr(desc, " warn cap")) |
317 | warncap = data / 1000; | | 317 | warncap = data / 1000; |
318 | else if (strstr(desc, " low cap")) | | 318 | else if (strstr(desc, " low cap")) |
319 | lowcap = data / 1000; | | 319 | lowcap = data / 1000; |
320 | else if (strstr(desc, " last full cap")) { | | 320 | else if (strstr(desc, " last full cap")) { |
321 | lastcap += data / 1000; | | 321 | lastcap += data / 1000; |
322 | lastcap_valid = 1; | | 322 | lastcap_valid = 1; |
323 | } | | 323 | } |
324 | else if (strstr(desc, " design cap")) | | 324 | else if (strstr(desc, " design cap")) |
| @@ -327,26 +327,29 @@ acpiapm_get_powstat(void *opaque, u_int | | | @@ -327,26 +327,29 @@ acpiapm_get_powstat(void *opaque, u_int |
327 | strstr(desc, " charge rate") == NULL && | | 327 | strstr(desc, " charge rate") == NULL && |
328 | strstr(desc, " charge state") == NULL) { | | 328 | strstr(desc, " charge state") == NULL) { |
329 | cap += data / 1000; | | 329 | cap += data / 1000; |
330 | cap_valid = 1; | | 330 | cap_valid = 1; |
331 | pinfo->nbattery++; | | 331 | pinfo->nbattery++; |
332 | } | | 332 | } |
333 | else if (strstr(desc, " discharge rate")) { | | 333 | else if (strstr(desc, " discharge rate")) { |
334 | discharge += data / 1000; | | 334 | discharge += data / 1000; |
335 | discharge_valid = 1; | | 335 | discharge_valid = 1; |
336 | } | | 336 | } |
337 | } | | 337 | } |
338 | sysmonclose_envsys(0, 0, 0, &lwp0); | | 338 | sysmonclose_envsys(0, 0, 0, &lwp0); |
339 | | | 339 | |
| | | 340 | if (present == 0) |
| | | 341 | pinfo->battery_flags |= APM_BATT_FLAG_NO_SYSTEM_BATTERY; |
| | | 342 | |
340 | if (cap_valid > 0) { | | 343 | if (cap_valid > 0) { |
341 | if (warncap != -1 && cap < warncap) | | 344 | if (warncap != -1 && cap < warncap) |
342 | pinfo->battery_flags |= APM_BATT_FLAG_CRITICAL; | | 345 | pinfo->battery_flags |= APM_BATT_FLAG_CRITICAL; |
343 | else if (lowcap != -1) { | | 346 | else if (lowcap != -1) { |
344 | if (cap < lowcap) | | 347 | if (cap < lowcap) |
345 | pinfo->battery_flags |= APM_BATT_FLAG_LOW; | | 348 | pinfo->battery_flags |= APM_BATT_FLAG_LOW; |
346 | else | | 349 | else |
347 | pinfo->battery_flags |= APM_BATT_FLAG_HIGH; | | 350 | pinfo->battery_flags |= APM_BATT_FLAG_HIGH; |
348 | } | | 351 | } |
349 | if (lastcap_valid > 0 && lastcap != 0) | | 352 | if (lastcap_valid > 0 && lastcap != 0) |
350 | pinfo->battery_life = 100 * cap / lastcap; | | 353 | pinfo->battery_life = 100 * cap / lastcap; |
351 | else if (descap != -1 && descap != 0) | | 354 | else if (descap != -1 && descap != 0) |
352 | pinfo->battery_life = 100 * cap / descap; | | 355 | pinfo->battery_life = 100 * cap / descap; |