1/*-
2 * Copyright (c) 2005 Nate Lawson
3 * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29#include "opt_acpi.h"
30#include <sys/param.h>
31#include <sys/kernel.h>
32#include <sys/malloc.h>
33#include <sys/bus.h>
34#include <sys/ioccom.h>
35#include <sys/sysctl.h>
36
37#include <contrib/dev/acpica/include/acpi.h>
38
39#include <dev/acpica/acpivar.h>
40#include <dev/acpica/acpiio.h>
41
42/* Default seconds before re-sampling the battery state. */
43#define	ACPI_BATTERY_INFO_EXPIRE	5
44
45static int	acpi_batteries_initialized;
46static int	acpi_battery_info_expire = ACPI_BATTERY_INFO_EXPIRE;
47static struct	acpi_battinfo	acpi_battery_battinfo;
48static struct	sysctl_ctx_list	acpi_battery_sysctl_ctx;
49static struct	sysctl_oid	*acpi_battery_sysctl_tree;
50
51ACPI_SERIAL_DECL(battery, "ACPI generic battery");
52
53static void acpi_reset_battinfo(struct acpi_battinfo *info);
54static void acpi_battery_clean_str(char *str, int len);
55static device_t acpi_battery_find_dev(u_int logical_unit);
56static int acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg);
57static int acpi_battery_sysctl(SYSCTL_HANDLER_ARGS);
58static int acpi_battery_units_sysctl(SYSCTL_HANDLER_ARGS);
59static int acpi_battery_init(void);
60
61int
62acpi_battery_register(device_t dev)
63{
64    int error;
65
66    ACPI_SERIAL_BEGIN(battery);
67    error = acpi_battery_init();
68    ACPI_SERIAL_END(battery);
69
70    return (error);
71}
72
73int
74acpi_battery_remove(device_t dev)
75{
76
77    return (0);
78}
79
80int
81acpi_battery_get_units(void)
82{
83    devclass_t batt_dc;
84
85    batt_dc = devclass_find("battery");
86    if (batt_dc == NULL)
87	return (0);
88    return (devclass_get_count(batt_dc));
89}
90
91int
92acpi_battery_get_info_expire(void)
93{
94
95    return (acpi_battery_info_expire);
96}
97
98/* Check _BST results for validity. */
99int
100acpi_battery_bst_valid(struct acpi_bst *bst)
101{
102
103    return (bst->state != ACPI_BATT_STAT_NOT_PRESENT &&
104	bst->cap != ACPI_BATT_UNKNOWN && bst->volt != ACPI_BATT_UNKNOWN);
105}
106
107/* Check _BI[FX] results for validity. */
108int
109acpi_battery_bix_valid(struct acpi_bix *bix)
110{
111
112    return (bix->lfcap != 0);
113}
114
115/* Get info about one or all batteries. */
116int
117acpi_battery_get_battinfo(device_t dev, struct acpi_battinfo *battinfo)
118{
119    int	batt_stat, devcount, dev_idx, error, i;
120    int total_cap, total_lfcap, total_min, valid_rate, valid_units;
121    devclass_t batt_dc;
122    device_t batt_dev;
123    struct acpi_bst *bst;
124    struct acpi_bix *bix;
125    struct acpi_battinfo *bi;
126
127    /*
128     * Get the battery devclass and max unit for battery devices.  If there
129     * are none or error, return immediately.
130     */
131    batt_dc = devclass_find("battery");
132    if (batt_dc == NULL)
133	return (ENXIO);
134    devcount = devclass_get_maxunit(batt_dc);
135    if (devcount == 0)
136	return (ENXIO);
137
138    /*
139     * Allocate storage for all _BST data, their derived battinfo data,
140     * and the current battery's _BIX (or _BIF) data.
141     */
142    bst = malloc(devcount * sizeof(*bst), M_TEMP, M_WAITOK | M_ZERO);
143    bi = malloc(devcount * sizeof(*bi), M_TEMP, M_WAITOK | M_ZERO);
144    bix = malloc(sizeof(*bix), M_TEMP, M_WAITOK | M_ZERO);
145
146    /*
147     * Pass 1:  for each battery that is present and valid, get its status,
148     * calculate percent capacity remaining, and sum all the current
149     * discharge rates.
150     */
151    dev_idx = -1;
152    batt_stat = valid_rate = valid_units = 0;
153    total_cap = total_lfcap = 0;
154    for (i = 0; i < devcount; i++) {
155	/* Default info for every battery is "not present". */
156	acpi_reset_battinfo(&bi[i]);
157
158	/*
159	 * Find the device.  Since devcount is in terms of max units, this
160	 * may be a sparse array so skip devices that aren't present.
161	 */
162	batt_dev = devclass_get_device(batt_dc, i);
163	if (batt_dev == NULL)
164	    continue;
165
166	/* If examining a specific battery and this is it, record its index. */
167	if (dev != NULL && dev == batt_dev)
168	    dev_idx = i;
169
170	/*
171	 * Be sure we can get various info from the battery.
172	 */
173	if (ACPI_BATT_GET_STATUS(batt_dev, &bst[i]) != 0 ||
174	    ACPI_BATT_GET_INFO(batt_dev, bix, sizeof(*bix)) != 0)
175		continue;
176
177	/* If a battery is not installed, we sometimes get strange values. */
178	if (!acpi_battery_bst_valid(&bst[i]) ||
179	    !acpi_battery_bix_valid(bix))
180	    continue;
181
182	/*
183	 * Record current state.  If both charging and discharging are set,
184	 * ignore the charging flag.
185	 */
186	valid_units++;
187	if ((bst[i].state & ACPI_BATT_STAT_DISCHARG) != 0)
188	    bst[i].state &= ~ACPI_BATT_STAT_CHARGING;
189	batt_stat |= bst[i].state;
190	bi[i].state = bst[i].state;
191
192	/*
193	 * If the battery info is in terms of mA, convert to mW by
194	 * multiplying by the design voltage.  If the design voltage
195	 * is 0 (due to some error reading the battery), skip this
196	 * conversion.
197	 */
198	if (bix->units == ACPI_BIX_UNITS_MA && bix->dvol != 0 && dev == NULL) {
199	    bst[i].rate = (bst[i].rate * bix->dvol) / 1000;
200	    bst[i].cap = (bst[i].cap * bix->dvol) / 1000;
201	    bix->lfcap = (bix->lfcap * bix->dvol) / 1000;
202	}
203
204	/*
205	 * The calculation above may set bix->lfcap to zero. This was
206	 * seen on a laptop with a broken battery. The result of the
207	 * division was rounded to zero.
208	 */
209	if (!acpi_battery_bix_valid(bix))
210	    continue;
211
212	/*
213	 * Some laptops report the "design-capacity" instead of the
214	 * "real-capacity" when the battery is fully charged.  That breaks
215	 * the above arithmetic as it needs to be 100% maximum.
216	 */
217	if (bst[i].cap > bix->lfcap)
218	    bst[i].cap = bix->lfcap;
219
220	/* Calculate percent capacity remaining. */
221	bi[i].cap = (100 * bst[i].cap) / bix->lfcap;
222
223	/* If this battery is not present, don't use its capacity. */
224	if (bi[i].cap != -1) {
225	    total_cap += bst[i].cap;
226	    total_lfcap += bix->lfcap;
227	}
228
229	/*
230	 * On systems with more than one battery, they may get used
231	 * sequentially, thus bst.rate may only signify the one currently
232	 * in use.  For the remaining batteries, bst.rate will be zero,
233	 * which makes it impossible to calculate the total remaining time.
234	 * Therefore, we sum the bst.rate for batteries in the discharging
235	 * state and use the sum to calculate the total remaining time.
236	 */
237	if (bst[i].rate != ACPI_BATT_UNKNOWN &&
238	    (bst[i].state & ACPI_BATT_STAT_DISCHARG) != 0)
239	    valid_rate += bst[i].rate;
240    }
241
242    /* If the caller asked for a device but we didn't find it, error. */
243    if (dev != NULL && dev_idx == -1) {
244	error = ENXIO;
245	goto out;
246    }
247
248    /* Pass 2:  calculate capacity and remaining time for all batteries. */
249    total_min = 0;
250    for (i = 0; i < devcount; i++) {
251	/*
252	 * If any batteries are discharging, use the sum of the bst.rate
253	 * values.  Otherwise, we are on AC power, and there is infinite
254	 * time remaining for this battery until we go offline.
255	 */
256	if (valid_rate > 0)
257	    bi[i].min = (60 * bst[i].cap) / valid_rate;
258	else
259	    bi[i].min = 0;
260	total_min += bi[i].min;
261    }
262
263    /*
264     * Return total battery percent and time remaining.  If there are
265     * no valid batteries, report values as unknown.
266     */
267    if (valid_units > 0) {
268	if (dev == NULL) {
269	    /*
270	     * Avoid division by zero if none of the batteries had valid
271	     * capacity info.
272	     */
273	    if (total_lfcap > 0)
274		battinfo->cap = (total_cap * 100) / total_lfcap;
275	    else
276		battinfo->cap = 0;
277	    battinfo->min = total_min;
278	    battinfo->state = batt_stat;
279	    battinfo->rate = valid_rate;
280	} else {
281	    battinfo->cap = bi[dev_idx].cap;
282	    battinfo->min = bi[dev_idx].min;
283	    battinfo->state = bi[dev_idx].state;
284	    battinfo->rate = bst[dev_idx].rate;
285	}
286
287	/*
288	 * If the queried battery has no discharge rate or is charging,
289	 * report that we don't know the remaining time.
290	 */
291	if (valid_rate == 0 || (battinfo->state & ACPI_BATT_STAT_CHARGING))
292	    battinfo->min = -1;
293    } else
294	acpi_reset_battinfo(battinfo);
295
296    error = 0;
297
298out:
299    free(bi, M_TEMP);
300    free(bix, M_TEMP);
301    free(bst, M_TEMP);
302    return (error);
303}
304
305static void
306acpi_reset_battinfo(struct acpi_battinfo *info)
307{
308    info->cap = -1;
309    info->min = -1;
310    info->state = ACPI_BATT_STAT_NOT_PRESENT;
311    info->rate = -1;
312}
313
314/* Make string printable, removing invalid chars. */
315static void
316acpi_battery_clean_str(char *str, int len)
317{
318    int i;
319
320    for (i = 0; i < len && *str != '\0'; i++, str++) {
321	if (!isprint(*str))
322	    *str = '?';
323    }
324
325    /* NUL-terminate the string if we reached the end. */
326    if (i == len)
327	*str = '\0';
328}
329
330/*
331 * The battery interface deals with devices and methods but userland
332 * expects a logical unit number.  Convert a logical unit to a device_t.
333 */
334static device_t
335acpi_battery_find_dev(u_int logical_unit)
336{
337    int found_unit, i, maxunit;
338    device_t dev;
339    devclass_t batt_dc;
340
341    dev = NULL;
342    found_unit = 0;
343    batt_dc = devclass_find("battery");
344    maxunit = devclass_get_maxunit(batt_dc);
345    for (i = 0; i < maxunit; i++) {
346	dev = devclass_get_device(batt_dc, i);
347	if (dev == NULL)
348	    continue;
349	if (logical_unit == found_unit)
350	    break;
351	found_unit++;
352	dev = NULL;
353    }
354
355    return (dev);
356}
357
358static int
359acpi_battery_ioctl(u_long cmd, caddr_t addr, void *arg)
360{
361    union acpi_battery_ioctl_arg *ioctl_arg;
362    int error, unit;
363    device_t dev;
364
365    /* For commands that use the ioctl_arg struct, validate it first. */
366    error = ENXIO;
367    unit = 0;
368    dev = NULL;
369    ioctl_arg = NULL;
370    if (IOCPARM_LEN(cmd) == sizeof(union acpi_battery_ioctl_arg) ||
371        IOCPARM_LEN(cmd) == sizeof(union acpi_battery_ioctl_arg_v1)) {
372	ioctl_arg = (union acpi_battery_ioctl_arg *)addr;
373	unit = ioctl_arg->unit;
374	if (unit != ACPI_BATTERY_ALL_UNITS)
375	    dev = acpi_battery_find_dev(unit);
376    }
377
378    /*
379     * No security check required: information retrieval only.  If
380     * new functions are added here, a check might be required.
381     */
382    /* Unit check */
383    switch (cmd) {
384    case ACPIIO_BATT_GET_UNITS:
385	*(int *)addr = acpi_battery_get_units();
386	error = 0;
387	break;
388    case ACPIIO_BATT_GET_BATTINFO:
389    case ACPIIO_BATT_GET_BATTINFO_V1:
390	if (dev != NULL || unit == ACPI_BATTERY_ALL_UNITS) {
391	    bzero(&ioctl_arg->battinfo, sizeof(ioctl_arg->battinfo));
392	    error = acpi_battery_get_battinfo(dev, &ioctl_arg->battinfo);
393	}
394	break;
395    case ACPIIO_BATT_GET_BIF:
396	if (dev != NULL) {
397	    bzero(&ioctl_arg->bif, sizeof(ioctl_arg->bif));
398	    error = ACPI_BATT_GET_INFO(dev, &ioctl_arg->bif,
399		sizeof(ioctl_arg->bif));
400	}
401	break;
402    case ACPIIO_BATT_GET_BIX:
403	if (dev != NULL) {
404	    bzero(&ioctl_arg->bix, sizeof(ioctl_arg->bix));
405	    error = ACPI_BATT_GET_INFO(dev, &ioctl_arg->bix,
406		sizeof(ioctl_arg->bix));
407	}
408	break;
409    case ACPIIO_BATT_GET_BST:
410    case ACPIIO_BATT_GET_BST_V1:
411	if (dev != NULL) {
412	    bzero(&ioctl_arg->bst, sizeof(ioctl_arg->bst));
413	    error = ACPI_BATT_GET_STATUS(dev, &ioctl_arg->bst);
414	}
415	break;
416    default:
417	error = EINVAL;
418    }
419
420    /* Sanitize the string members. */
421    switch (cmd) {
422    case ACPIIO_BATT_GET_BIX:
423    case ACPIIO_BATT_GET_BIF:
424	    /*
425	     * Remove invalid characters.  Perhaps this should be done
426	     * within a convenience function so all callers get the
427	     * benefit.
428	     */
429	    acpi_battery_clean_str(ioctl_arg->bix.model,
430		sizeof(ioctl_arg->bix.model));
431	    acpi_battery_clean_str(ioctl_arg->bix.serial,
432		sizeof(ioctl_arg->bix.serial));
433	    acpi_battery_clean_str(ioctl_arg->bix.type,
434		sizeof(ioctl_arg->bix.type));
435	    acpi_battery_clean_str(ioctl_arg->bix.oeminfo,
436		sizeof(ioctl_arg->bix.oeminfo));
437    };
438
439    return (error);
440}
441
442static int
443acpi_battery_sysctl(SYSCTL_HANDLER_ARGS)
444{
445    int val, error;
446
447    acpi_battery_get_battinfo(NULL, &acpi_battery_battinfo);
448    val = *(u_int *)oidp->oid_arg1;
449    error = sysctl_handle_int(oidp, &val, 0, req);
450    return (error);
451}
452
453static int
454acpi_battery_units_sysctl(SYSCTL_HANDLER_ARGS)
455{
456    int count, error;
457
458    count = acpi_battery_get_units();
459    error = sysctl_handle_int(oidp, &count, 0, req);
460    return (error);
461}
462
463static int
464acpi_battery_init(void)
465{
466    struct acpi_softc	*sc;
467    device_t		 dev;
468    int	 		 error;
469
470    ACPI_SERIAL_ASSERT(battery);
471
472    if (acpi_batteries_initialized)
473	    return(0);
474
475    error = ENXIO;
476    dev = devclass_get_device(devclass_find("acpi"), 0);
477    if (dev == NULL)
478	goto out;
479    sc = device_get_softc(dev);
480
481#define	ACPI_REGISTER_IOCTL(a, b, c) do {	\
482    error = acpi_register_ioctl(a, b, c);	\
483    if (error)					\
484	goto out;				\
485    } while (0)
486
487    ACPI_REGISTER_IOCTL(ACPIIO_BATT_GET_UNITS, acpi_battery_ioctl, NULL);
488    ACPI_REGISTER_IOCTL(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl, NULL);
489    ACPI_REGISTER_IOCTL(ACPIIO_BATT_GET_BATTINFO_V1, acpi_battery_ioctl, NULL);
490    ACPI_REGISTER_IOCTL(ACPIIO_BATT_GET_BIF, acpi_battery_ioctl, NULL);
491    ACPI_REGISTER_IOCTL(ACPIIO_BATT_GET_BIX, acpi_battery_ioctl, NULL);
492    ACPI_REGISTER_IOCTL(ACPIIO_BATT_GET_BST, acpi_battery_ioctl, NULL);
493    ACPI_REGISTER_IOCTL(ACPIIO_BATT_GET_BST_V1, acpi_battery_ioctl, NULL);
494#undef	ACPI_REGISTER_IOCTL
495
496    sysctl_ctx_init(&acpi_battery_sysctl_ctx);
497    acpi_battery_sysctl_tree = SYSCTL_ADD_NODE(&acpi_battery_sysctl_ctx,
498	SYSCTL_CHILDREN(sc->acpi_sysctl_tree), OID_AUTO, "battery",
499	CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "battery status and info");
500    SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
501	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
502	OID_AUTO, "life", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
503	&acpi_battery_battinfo.cap, 0, acpi_battery_sysctl, "I",
504	"percent capacity remaining");
505    SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
506	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
507	OID_AUTO, "time", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
508	&acpi_battery_battinfo.min, 0, acpi_battery_sysctl, "I",
509	"remaining time in minutes");
510    SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
511	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
512	OID_AUTO, "rate", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
513	&acpi_battery_battinfo.rate, 0, acpi_battery_sysctl, "I",
514	"present rate in mW");
515    SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
516	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
517	OID_AUTO, "state", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
518	&acpi_battery_battinfo.state, 0, acpi_battery_sysctl, "I",
519	"current status flags");
520    SYSCTL_ADD_PROC(&acpi_battery_sysctl_ctx,
521	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
522	OID_AUTO, "units", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
523	NULL, 0, acpi_battery_units_sysctl, "I", "number of batteries");
524    SYSCTL_ADD_INT(&acpi_battery_sysctl_ctx,
525	SYSCTL_CHILDREN(acpi_battery_sysctl_tree),
526	OID_AUTO, "info_expire", CTLFLAG_RW,
527	&acpi_battery_info_expire, 0,
528	"time in seconds until info is refreshed");
529
530    acpi_batteries_initialized = TRUE;
531
532out:
533    if (error) {
534	acpi_deregister_ioctl(ACPIIO_BATT_GET_UNITS, acpi_battery_ioctl);
535	acpi_deregister_ioctl(ACPIIO_BATT_GET_BATTINFO, acpi_battery_ioctl);
536	acpi_deregister_ioctl(ACPIIO_BATT_GET_BATTINFO_V1, acpi_battery_ioctl);
537	acpi_deregister_ioctl(ACPIIO_BATT_GET_BIF, acpi_battery_ioctl);
538	acpi_deregister_ioctl(ACPIIO_BATT_GET_BIX, acpi_battery_ioctl);
539	acpi_deregister_ioctl(ACPIIO_BATT_GET_BST, acpi_battery_ioctl);
540	acpi_deregister_ioctl(ACPIIO_BATT_GET_BST_V1, acpi_battery_ioctl);
541    }
542    return (error);
543}
544