Bug #1529 ยป 0001-New-aibs-4-driver-for-ASUSTeK-AI-Booster-ACPI-ATK011.2009-09-24T031633-0400.patch
share/man/man4/Makefile | ||
---|---|---|
ahc.4 \
|
||
ahci.4 \
|
||
ahd.4 \
|
||
aibs.4 \
|
||
ale.4 \
|
||
altq.4 \
|
||
amd.4 \
|
share/man/man4/aibs.4 | ||
---|---|---|
.\" $OpenBSD: aibs.4,v 1.4 2009/07/30 06:30:45 jmc Exp $
|
||
.\"
|
||
.\" Copyright (c) 2009 Constantine A. Murenin <cnst+dfly@bugmail.mojo.ru>
|
||
.\"
|
||
.\" Permission to use, copy, modify, and distribute this software for any
|
||
.\" purpose with or without fee is hereby granted, provided that the above
|
||
.\" copyright notice and this permission notice appear in all copies.
|
||
.\"
|
||
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
.\"
|
||
.Dd September 23, 2009
|
||
.Dt AIBS 4
|
||
.Os
|
||
.Sh NAME
|
||
.Nm aibs
|
||
.Nd "ASUSTeK AI Booster ACPI ATK0110 voltage, temperature and fan sensor"
|
||
.Sh SYNOPSIS
|
||
To compile this driver into the kernel,
|
||
place the following lines in your
|
||
kernel configuration file:
|
||
.Bd -ragged -offset indent
|
||
.Cd "device acpi"
|
||
.Cd "device aibs"
|
||
.Ed
|
||
.Pp
|
||
Alternatively, to load the driver as a
|
||
module at boot time, place the following lines in
|
||
.Xr loader.conf 5 :
|
||
.Bd -literal -offset indent
|
||
acpi_load="YES"
|
||
aibs_load="YES"
|
||
.Ed
|
||
.Sh DESCRIPTION
|
||
The
|
||
.Nm
|
||
driver provides support for the voltage, temperature and fan sensors
|
||
available through the
|
||
ATK0110
|
||
ASOC
|
||
ACPI
|
||
device
|
||
on ASUSTeK motherboards.
|
||
The number of sensors of each type,
|
||
as well as the description of each sensor,
|
||
varies according to the motherboard.
|
||
.Pp
|
||
The driver supports an arbitrary set of sensors,
|
||
provides descriptions regarding what each sensor is used for,
|
||
and reports whether each sensor is within the specifications
|
||
as defined by the motherboard manufacturer through ACPI.
|
||
.Pp
|
||
The
|
||
.Nm
|
||
driver supports sensor states as follows:
|
||
temperature sensors can have a state of
|
||
.Dv OK ,
|
||
.Dv WARN ,
|
||
.Dv CRIT
|
||
or
|
||
.Dv UNKNOWN ;
|
||
fan and voltage sensors can have a state of
|
||
.Dv OK
|
||
or
|
||
.Dv WARN
|
||
only.
|
||
Temperature sensors that have a reading of 0
|
||
are marked as invalid and their state is set to
|
||
.Dv UNKNOWN ,
|
||
whereas all other sensors are always assumed valid.
|
||
Temperature sensors have two upper limits
|
||
.Dv ( WARN
|
||
and
|
||
.Dv CRIT ) ,
|
||
fan sensors have either only the lower limit, or
|
||
one lower and one upper limit,
|
||
and voltage sensors always have a lower and an upper limit.
|
||
.Pp
|
||
Sensor values are made available through the
|
||
.Dv HW_SENSORS
|
||
.Xr sysctl 3
|
||
interface,
|
||
and can be monitored with the
|
||
.Xr systat 1
|
||
.Ar sensors
|
||
display,
|
||
.Xr sensorsd 8
|
||
and
|
||
.Xr sysctl 8
|
||
.Ar hw.sensors .
|
||
For example, on an Asus Stricker Extreme motherboard:
|
||
.Bd -literal -offset indent
|
||
$ sysctl hw.sensors.aibs0
|
||
hw.sensors.aibs0.temp0=31.00 degC (CPU Temperature), OK
|
||
hw.sensors.aibs0.temp1=43.00 degC (MB Temperature), OK
|
||
hw.sensors.aibs0.fan0=2490 RPM (CPU FAN Speed), OK
|
||
hw.sensors.aibs0.fan1=0 RPM (CHASSIS FAN Speed), WARNING
|
||
hw.sensors.aibs0.fan2=0 RPM (OPT1 FAN Speed), WARNING
|
||
hw.sensors.aibs0.fan3=0 RPM (OPT2 FAN Speed), WARNING
|
||
hw.sensors.aibs0.fan4=0 RPM (OPT3 FAN Speed), WARNING
|
||
hw.sensors.aibs0.fan5=0 RPM (OPT4 FAN Speed), WARNING
|
||
hw.sensors.aibs0.fan6=0 RPM (OPT5 FAN Speed), WARNING
|
||
hw.sensors.aibs0.fan7=0 RPM (PWR FAN Speed), WARNING
|
||
hw.sensors.aibs0.volt0=1.26 VDC (Vcore Voltage), OK
|
||
hw.sensors.aibs0.volt1=3.25 VDC ( +3.3 Voltage), OK
|
||
hw.sensors.aibs0.volt2=4.95 VDC ( +5.0 Voltage), OK
|
||
hw.sensors.aibs0.volt3=11.78 VDC (+12.0 Voltage), OK
|
||
hw.sensors.aibs0.volt4=1.23 VDC (1.2VHT Voltage), OK
|
||
hw.sensors.aibs0.volt5=1.50 VDC (SB CORE Voltage), OK
|
||
hw.sensors.aibs0.volt6=1.25 VDC (CPU VTT Voltage), OK
|
||
hw.sensors.aibs0.volt7=0.93 VDC (DDR2 TERM Voltage), OK
|
||
hw.sensors.aibs0.volt8=1.23 VDC (NB CORE Voltage), OK
|
||
hw.sensors.aibs0.volt9=1.87 VDC (MEMORY Voltage), OK
|
||
.Ed
|
||
.Pp
|
||
Generally, sensors provided by the
|
||
.Nm
|
||
driver may also be supported by a variety of other drivers,
|
||
such as
|
||
.Xr lm 4
|
||
or
|
||
.Xr it 4 .
|
||
The precise collection of
|
||
.Nm
|
||
sensors is comprised of the sensors
|
||
specifically utilised in the motherboard
|
||
design, which may be supported through
|
||
a combination of one or more physical hardware monitoring chips.
|
||
.Pp
|
||
The
|
||
.Nm
|
||
driver, however, provides the following advantages
|
||
when compared to the native hardware monitoring drivers:
|
||
.Bl -bullet
|
||
.It
|
||
Sensor values from
|
||
.Nm
|
||
are expected to be more reliable.
|
||
For example, voltage sensors in many hardware monitoring chips
|
||
can only sense voltage from 0 to 2 or 4 volts, and the excessive
|
||
voltage is removed by the resistors, which may vary with the motherboard
|
||
and with the voltage that is being sensed.
|
||
In
|
||
.Nm ,
|
||
the required resistor factors are provided by
|
||
the motherboard manufacturer through ACPI;
|
||
in the native drivers, the resistor factors
|
||
are encoded into the driver based on the chip manufacturer's recommendations.
|
||
In essence, sensor values from
|
||
.Nm
|
||
are very likely to be identical to the readings from the
|
||
Hardware Monitor screen in the BIOS.
|
||
.It
|
||
Sensor descriptions from
|
||
.Nm
|
||
are more likely to match the markings on the motherboard.
|
||
.It
|
||
Sensor status is supported by
|
||
.Nm .
|
||
The status is reported based on the acceptable range of values
|
||
for each individual sensor as suggested by the motherboard manufacturer.
|
||
For example, the threshold for the CPU temperature sensor is likely
|
||
to be significantly higher than that for the chassis temperature sensor.
|
||
.It
|
||
Support for newer chips in
|
||
.Nm .
|
||
Newer chips may miss a native driver,
|
||
but should be supported through
|
||
.Nm
|
||
regardless.
|
||
.El
|
||
.Pp
|
||
As a result, sensor readings from the actual
|
||
native hardware monitoring drivers
|
||
are redundant when
|
||
.Nm
|
||
is present, and
|
||
may be ignored as appropriate.
|
||
Whereas on
|
||
.Ox
|
||
the native drivers have to be specifically disabled should
|
||
their presence be judged unnecessary,
|
||
on
|
||
.Dx
|
||
the
|
||
.Xr lm 4
|
||
and
|
||
.Xr it 4
|
||
are not probed provided that
|
||
.Xr acpi 4
|
||
is configured and the system potentially supports
|
||
the hardware monitoring chip through ACPI.
|
||
.Sh SEE ALSO
|
||
.Xr systat 1 ,
|
||
.Xr sysctl 3 ,
|
||
.Xr acpi 4 ,
|
||
.Xr intro 4 ,
|
||
.Xr sensorsd 8 ,
|
||
.Xr sysctl 8
|
||
.Sh HISTORY
|
||
The
|
||
.Nm
|
||
driver first appeared in
|
||
.Ox 4.7
|
||
and
|
||
.Dx 2.5 .
|
||
.Sh AUTHORS
|
||
The
|
||
.Nm
|
||
driver was written for
|
||
.Ox
|
||
and
|
||
.Dx
|
||
by
|
||
.An Constantine A. Murenin Aq http://cnst.su/ ,
|
||
David R. Cheriton School of Computer Science,
|
||
University of Waterloo.
|
sys/conf/files | ||
---|---|---|
${OSACPI_MI_DIR}/acpi_toshiba/acpi_toshiba.c optional acpi_toshiba acpi
|
||
${OSACPI_MI_DIR}/acpi_thinkpad/acpi_thinkpad.c optional acpi_thinkpad acpi
|
||
${OSACPI_MI_DIR}/acpi_video/acpi_video.c optional acpi_video acpi
|
||
${OSACPI_MI_DIR}/aibs/atk0110.c optional aibs acpi
|
||
# ACPICA code
|
||
${ACPICA_DIR}/debugger/dbcmds.c optional acpi acpi_debug
|
sys/config/LINT | ||
---|---|---|
device acpi_thinkpad # ThinkPad support
|
||
device acpi_toshiba # Toshiba laptop support
|
||
device acpi_video # ACPI video extensions
|
||
device aibs # ASUSTeK AI Booster (ACPI ASOC ATK0110)
|
||
device pmtimer # adjust the system clock after resume
|
||
# DRM options:
|
sys/dev/acpica5/Makefile | ||
---|---|---|
${MAKE} -f ${SYSDIR}/${OSACPI_MD_DIR}/Makefile \
|
||
MAKESRCPATH=${SYSDIR}/${OSACPI_MD_DIR}
|
||
SUBDIR= acpi_asus acpi_thinkpad acpi_toshiba acpi_video
|
||
SUBDIR= acpi_asus acpi_thinkpad acpi_toshiba acpi_video aibs
|
||
all: ${PROG} ${SUBDIR}
|
||
.include <bsd.kmod.mk>
|
sys/dev/acpica5/aibs/Makefile | ||
---|---|---|
KMOD= aibs
|
||
CFLAGS+= -I${.OBJDIR}/.. -I${.CURDIR}/..
|
||
SRCS= atk0110.c
|
||
SRCS+= opt_acpi.h bus_if.h device_if.h
|
||
.include <bsd.kmod.mk>
|
sys/dev/acpica5/aibs/atk0110.c | ||
---|---|---|
/* $OpenBSD: atk0110.c,v 1.1 2009/07/23 01:38:16 cnst Exp $ */
|
||
/*
|
||
* Copyright (c) 2009 Constantine A. Murenin <cnst+dfly@bugmail.mojo.ru>
|
||
*
|
||
* Permission to use, copy, modify, and distribute this software for any
|
||
* purpose with or without fee is hereby granted, provided that the above
|
||
* copyright notice and this permission notice appear in all copies.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
*/
|
||
#include <sys/cdefs.h>
|
||
#include <sys/param.h>
|
||
#include <sys/systm.h>
|
||
#include <sys/kernel.h>
|
||
#include <sys/bus.h>
|
||
#include <sys/module.h>
|
||
#include <sys/malloc.h>
|
||
#include <sys/sensors.h>
|
||
#include "acpi.h"
|
||
#include "acpivar.h"
|
||
/*
|
||
* ASUSTeK AI Booster (ACPI ATK0110).
|
||
*
|
||
* This code was originally written for OpenBSD after the techniques
|
||
* described in the Linux's asus_atk0110.c and FreeBSD's acpi_aiboost.c
|
||
* were verified to be accurate on the actual hardware kindly provided by
|
||
* Sam Fourman Jr. It was subsequently ported from OpenBSD to DragonFly BSD.
|
||
*
|
||
* -- Constantine A. Murenin <http://cnst.su/>
|
||
*/
|
||
#define AIBS_MORE_SENSORS
|
||
#define AIBS_VERBOSE
|
||
struct aibs_sensor {
|
||
struct ksensor s;
|
||
int64_t i;
|
||
int64_t l;
|
||
int64_t h;
|
||
};
|
||
struct aibs_softc {
|
||
struct device *sc_dev;
|
||
ACPI_HANDLE sc_ah;
|
||
struct aibs_sensor *sc_asens_volt;
|
||
struct aibs_sensor *sc_asens_temp;
|
||
struct aibs_sensor *sc_asens_fan;
|
||
struct ksensordev sc_sensordev;
|
||
};
|
||
static int aibs_probe(struct device *);
|
||
static int aibs_attach(struct device *);
|
||
static int aibs_detach(struct device *);
|
||
static void aibs_refresh(void *);
|
||
static void aibs_attach_sif(struct aibs_softc *, enum sensor_type);
|
||
static void aibs_refresh_r(struct aibs_softc *, enum sensor_type);
|
||
static device_method_t aibs_methods[] = {
|
||
DEVMETHOD(device_probe, aibs_probe),
|
||
DEVMETHOD(device_attach, aibs_attach),
|
||
DEVMETHOD(device_detach, aibs_detach),
|
||
{ NULL, NULL }
|
||
};
|
||
static driver_t aibs_driver = {
|
||
"aibs",
|
||
aibs_methods,
|
||
sizeof(struct aibs_softc)
|
||
};
|
||
static devclass_t aibs_devclass;
|
||
DRIVER_MODULE(aibs, acpi, aibs_driver, aibs_devclass, NULL, NULL);
|
||
static char* aibs_hids[] = {
|
||
"ATK0110",
|
||
NULL
|
||
};
|
||
static int
|
||
aibs_probe(struct device *dev)
|
||
{
|
||
if (acpi_disabled("aibs") ||
|
||
ACPI_ID_PROBE(device_get_parent(dev), dev, aibs_hids) == NULL)
|
||
return ENXIO;
|
||
device_set_desc(dev, "ASUSTeK AI Booster (ACPI ASOC ATK0110)");
|
||
return 0;
|
||
}
|
||
static int
|
||
aibs_attach(struct device *dev)
|
||
{
|
||
struct aibs_softc *sc;
|
||
sc = device_get_softc(dev);
|
||
sc->sc_dev = dev;
|
||
sc->sc_ah = acpi_get_handle(dev);
|
||
strlcpy(sc->sc_sensordev.xname, device_get_nameunit(dev),
|
||
sizeof(sc->sc_sensordev.xname));
|
||
aibs_attach_sif(sc, SENSOR_VOLTS_DC);
|
||
aibs_attach_sif(sc, SENSOR_TEMP);
|
||
aibs_attach_sif(sc, SENSOR_FANRPM);
|
||
if (sc->sc_sensordev.sensors_count == 0) {
|
||
device_printf(dev, "no sensors found\n");
|
||
return ENXIO;
|
||
}
|
||
if (sensor_task_register(sc, aibs_refresh, 5)) {
|
||
device_printf(dev, "unable to register update task\n");
|
||
return ENXIO;
|
||
}
|
||
sensordev_install(&sc->sc_sensordev);
|
||
return 0;
|
||
}
|
||
static void
|
||
aibs_attach_sif(struct aibs_softc *sc, enum sensor_type st)
|
||
{
|
||
ACPI_STATUS s;
|
||
ACPI_BUFFER b;
|
||
ACPI_OBJECT *bp, *o;
|
||
int i, n;
|
||
char name[] = "?SIF";
|
||
struct aibs_sensor *as;
|
||
switch (st) {
|
||
case SENSOR_TEMP:
|
||
name[0] = 'T';
|
||
break;
|
||
case SENSOR_FANRPM:
|
||
name[0] = 'F';
|
||
break;
|
||
case SENSOR_VOLTS_DC:
|
||
name[0] = 'V';
|
||
break;
|
||
default:
|
||
return;
|
||
}
|
||
b.Length = ACPI_ALLOCATE_BUFFER;
|
||
s = AcpiEvaluateObjectTyped(sc->sc_ah, name, NULL, &b,
|
||
ACPI_TYPE_PACKAGE);
|
||
if (ACPI_FAILURE(s)) {
|
||
device_printf(sc->sc_dev, "%s not found\n", name);
|
||
return;
|
||
}
|
||
bp = b.Pointer;
|
||
o = bp->Package.Elements;
|
||
if (o[0].Type != ACPI_TYPE_INTEGER) {
|
||
device_printf(sc->sc_dev, "%s[0]: invalid type\n", name);
|
||
AcpiOsFree(b.Pointer);
|
||
return;
|
||
}
|
||
n = o[0].Integer.Value;
|
||
if (bp->Package.Count - 1 < n) {
|
||
device_printf(sc->sc_dev, "%s: invalid package\n", name);
|
||
AcpiOsFree(b.Pointer);
|
||
return;
|
||
} else if (bp->Package.Count - 1 > n) {
|
||
int on = n;
|
||
#ifdef AIBS_MORE_SENSORS
|
||
n = bp->Package.Count - 1;
|
||
#endif
|
||
device_printf(sc->sc_dev, "%s: misformed package: %i/%i"
|
||
", assume %i\n", name, on, bp->Package.Count - 1, n);
|
||
}
|
||
if (n < 1) {
|
||
device_printf(sc->sc_dev, "%s: no members in the package\n",
|
||
name);
|
||
AcpiOsFree(b.Pointer);
|
||
return;
|
||
}
|
||
as = kmalloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO);
|
||
if (as == NULL) {
|
||
device_printf(sc->sc_dev, "%s: malloc fail\n", name);
|
||
AcpiOsFree(b.Pointer);
|
||
return;
|
||
}
|
||
switch (st) {
|
||
case SENSOR_TEMP:
|
||
sc->sc_asens_temp = as;
|
||
break;
|
||
case SENSOR_FANRPM:
|
||
sc->sc_asens_fan = as;
|
||
break;
|
||
case SENSOR_VOLTS_DC:
|
||
sc->sc_asens_volt = as;
|
||
break;
|
||
default:
|
||
/* NOTREACHED */
|
||
return;
|
||
}
|
||
for (i = 0, o++; i < n; i++, o++) {
|
||
ACPI_OBJECT *oi;
|
||
/* acpica5 automatically evaluates the referenced package */
|
||
if(o[0].Type != ACPI_TYPE_PACKAGE) {
|
||
device_printf(sc->sc_dev,
|
||
"%s: %i: not a package: %i type\n",
|
||
name, i, o[0].Type);
|
||
continue;
|
||
}
|
||
oi = o[0].Package.Elements;
|
||
if (o[0].Package.Count != 5 ||
|
||
oi[0].Type != ACPI_TYPE_INTEGER ||
|
||
oi[1].Type != ACPI_TYPE_STRING ||
|
||
oi[2].Type != ACPI_TYPE_INTEGER ||
|
||
oi[3].Type != ACPI_TYPE_INTEGER ||
|
||
oi[4].Type != ACPI_TYPE_INTEGER) {
|
||
device_printf(sc->sc_dev,
|
||
"%s: %i: invalid package\n",
|
||
name, i);
|
||
continue;
|
||
}
|
||
as[i].i = oi[0].Integer.Value;
|
||
strlcpy(as[i].s.desc, oi[1].String.Pointer,
|
||
sizeof(as[i].s.desc));
|
||
as[i].l = oi[2].Integer.Value;
|
||
as[i].h = oi[3].Integer.Value;
|
||
as[i].s.type = st;
|
||
#ifdef AIBS_VERBOSE
|
||
device_printf(sc->sc_dev, "%c%i: "
|
||
"0x%08llx %20s %5lli / %5lli 0x%llx\n",
|
||
name[0], i,
|
||
as[i].i, as[i].s.desc, as[i].l, as[i].h,
|
||
oi[4].Integer.Value);
|
||
#endif
|
||
sensor_attach(&sc->sc_sensordev, &as[i].s);
|
||
}
|
||
AcpiOsFree(b.Pointer);
|
||
return;
|
||
}
|
||
static int
|
||
aibs_detach(struct device *dev)
|
||
{
|
||
struct aibs_softc *sc = device_get_softc(dev);
|
||
sensordev_deinstall(&sc->sc_sensordev);
|
||
sensor_task_unregister(sc);
|
||
if (sc->sc_asens_volt != NULL)
|
||
kfree(sc->sc_asens_volt, M_DEVBUF);
|
||
if (sc->sc_asens_temp != NULL)
|
||
kfree(sc->sc_asens_temp, M_DEVBUF);
|
||
if (sc->sc_asens_fan != NULL)
|
||
kfree(sc->sc_asens_fan, M_DEVBUF);
|
||
return 0;
|
||
}
|
||
#ifdef AIBS_VERBOSE
|
||
#define ddevice_printf(x...) device_printf(x)
|
||
#else
|
||
#define ddevice_printf(x...)
|
||
#endif
|
||
static void
|
||
aibs_refresh(void *arg)
|
||
{
|
||
struct aibs_softc *sc = arg;
|
||
aibs_refresh_r(sc, SENSOR_VOLTS_DC);
|
||
aibs_refresh_r(sc, SENSOR_TEMP);
|
||
aibs_refresh_r(sc, SENSOR_FANRPM);
|
||
}
|
||
static void
|
||
aibs_refresh_r(struct aibs_softc *sc, enum sensor_type st)
|
||
{
|
||
ACPI_STATUS rs;
|
||
ACPI_HANDLE rh;
|
||
int i, n = sc->sc_sensordev.maxnumt[st];
|
||
char *name;
|
||
struct aibs_sensor *as;
|
||
switch (st) {
|
||
case SENSOR_TEMP:
|
||
name = "RTMP";
|
||
as = sc->sc_asens_temp;
|
||
break;
|
||
case SENSOR_FANRPM:
|
||
name = "RFAN";
|
||
as = sc->sc_asens_fan;
|
||
break;
|
||
case SENSOR_VOLTS_DC:
|
||
name = "RVLT";
|
||
as = sc->sc_asens_volt;
|
||
break;
|
||
default:
|
||
return;
|
||
}
|
||
if (as == NULL)
|
||
return;
|
||
rs = AcpiGetHandle(sc->sc_ah, name, &rh);
|
||
if (ACPI_FAILURE(rs)) {
|
||
ddevice_printf(sc->sc_dev, "%s: method handle not found\n",
|
||
name);
|
||
for (i = 0; i < n; i++)
|
||
as[i].s.flags |= SENSOR_FINVALID;
|
||
return;
|
||
}
|
||
for (i = 0; i < n; i++) {
|
||
ACPI_OBJECT p, *bp;
|
||
ACPI_OBJECT_LIST mp;
|
||
ACPI_BUFFER b;
|
||
int64_t v;
|
||
struct ksensor *s = &as[i].s;
|
||
const int64_t l = as[i].l, h = as[i].h;
|
||
p.Type = ACPI_TYPE_INTEGER;
|
||
p.Integer.Value = as[i].i;
|
||
mp.Count = 1;
|
||
mp.Pointer = &p;
|
||
b.Length = ACPI_ALLOCATE_BUFFER;
|
||
rs = AcpiEvaluateObjectTyped(rh, NULL, &mp, &b,
|
||
ACPI_TYPE_INTEGER);
|
||
if (ACPI_FAILURE(rs)) {
|
||
ddevice_printf(sc->sc_dev,
|
||
"%s: %i: evaluation failed\n",
|
||
name, i);
|
||
s->flags |= SENSOR_FINVALID;
|
||
continue;
|
||
}
|
||
bp = b.Pointer;
|
||
v = bp->Integer.Value;
|
||
AcpiOsFree(b.Pointer);
|
||
switch (st) {
|
||
case SENSOR_TEMP:
|
||
s->value = v * 100 * 1000 + 273150000;
|
||
if (v == 0) {
|
||
s->status = SENSOR_S_UNKNOWN;
|
||
s->flags |= SENSOR_FINVALID;
|
||
} else {
|
||
if (v > h)
|
||
s->status = SENSOR_S_CRIT;
|
||
else if (v > l)
|
||
s->status = SENSOR_S_WARN;
|
||
else
|
||
s->status = SENSOR_S_OK;
|
||
s->flags &= ~SENSOR_FINVALID;
|
||
}
|
||
break;
|
||
case SENSOR_FANRPM:
|
||
s->value = v;
|
||
/* some boards have strange limits for fans */
|
||
if ((l != 0 && l < v && v < h) ||
|
||
(l == 0 && v > h))
|
||
s->status = SENSOR_S_OK;
|
||
else
|
||
s->status = SENSOR_S_WARN;
|
||
s->flags &= ~SENSOR_FINVALID;
|
||
break;
|
||
case SENSOR_VOLTS_DC:
|
||
s->value = v * 1000;
|
||
if (l < v && v < h)
|
||
s->status = SENSOR_S_OK;
|
||
else
|
||
s->status = SENSOR_S_WARN;
|
||
s->flags &= ~SENSOR_FINVALID;
|
||
break;
|
||
default:
|
||
/* NOTREACHED */
|
||
break;
|
||
}
|
||
}
|
||
return;
|
||
}
|