0001-New-aibs-4-driver-for-ASUSTeK-AI-Booster-ACPI-ATK011.2009-09-24T031633-0400.patch

C++, 09/24/2009 10:10 PM

Download (18.9 KB)

View differences:

share/man/man4/Makefile
20 20
	ahc.4 \
21 21
	ahci.4 \
22 22
	ahd.4 \
23
	aibs.4 \
23 24
	ale.4 \
24 25
	altq.4 \
25 26
	amd.4 \
share/man/man4/aibs.4
1
.\"	$OpenBSD: aibs.4,v 1.4 2009/07/30 06:30:45 jmc Exp $
2
.\"
3
.\" Copyright (c) 2009 Constantine A. Murenin <cnst+dfly@bugmail.mojo.ru>
4
.\"
5
.\" Permission to use, copy, modify, and distribute this software for any
6
.\" purpose with or without fee is hereby granted, provided that the above
7
.\" copyright notice and this permission notice appear in all copies.
8
.\"
9
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
.\"
17
.Dd September 23, 2009
18
.Dt AIBS 4
19
.Os
20
.Sh NAME
21
.Nm aibs
22
.Nd "ASUSTeK AI Booster ACPI ATK0110 voltage, temperature and fan sensor"
23
.Sh SYNOPSIS
24
To compile this driver into the kernel,
25
place the following lines in your
26
kernel configuration file:
27
.Bd -ragged -offset indent
28
.Cd "device acpi"
29
.Cd "device aibs"
30
.Ed
31
.Pp
32
Alternatively, to load the driver as a
33
module at boot time, place the following lines in
34
.Xr loader.conf 5 :
35
.Bd -literal -offset indent
36
acpi_load="YES"
37
aibs_load="YES"
38
.Ed
39
.Sh DESCRIPTION
40
The
41
.Nm
42
driver provides support for the voltage, temperature and fan sensors
43
available through the
44
ATK0110
45
ASOC
46
ACPI
47
device
48
on ASUSTeK motherboards.
49
The number of sensors of each type,
50
as well as the description of each sensor,
51
varies according to the motherboard.
52
.Pp
53
The driver supports an arbitrary set of sensors,
54
provides descriptions regarding what each sensor is used for,
55
and reports whether each sensor is within the specifications
56
as defined by the motherboard manufacturer through ACPI.
57
.Pp
58
The
59
.Nm
60
driver supports sensor states as follows:
61
temperature sensors can have a state of
62
.Dv OK ,
63
.Dv WARN ,
64
.Dv CRIT
65
or
66
.Dv UNKNOWN ;
67
fan and voltage sensors can have a state of
68
.Dv OK
69
or
70
.Dv WARN
71
only.
72
Temperature sensors that have a reading of 0
73
are marked as invalid and their state is set to
74
.Dv UNKNOWN ,
75
whereas all other sensors are always assumed valid.
76
Temperature sensors have two upper limits
77
.Dv ( WARN
78
and
79
.Dv CRIT ) ,
80
fan sensors have either only the lower limit, or
81
one lower and one upper limit,
82
and voltage sensors always have a lower and an upper limit.
83
.Pp
84
Sensor values are made available through the
85
.Dv HW_SENSORS
86
.Xr sysctl 3
87
interface,
88
and can be monitored with the
89
.Xr systat 1
90
.Ar sensors
91
display,
92
.Xr sensorsd 8
93
and
94
.Xr sysctl 8
95
.Ar hw.sensors .
96
For example, on an Asus Stricker Extreme motherboard:
97
.Bd -literal -offset indent
98
$ sysctl hw.sensors.aibs0
99
hw.sensors.aibs0.temp0=31.00 degC (CPU Temperature), OK
100
hw.sensors.aibs0.temp1=43.00 degC (MB Temperature), OK
101
hw.sensors.aibs0.fan0=2490 RPM (CPU FAN Speed), OK
102
hw.sensors.aibs0.fan1=0 RPM (CHASSIS FAN Speed), WARNING
103
hw.sensors.aibs0.fan2=0 RPM (OPT1 FAN Speed), WARNING
104
hw.sensors.aibs0.fan3=0 RPM (OPT2 FAN Speed), WARNING
105
hw.sensors.aibs0.fan4=0 RPM (OPT3 FAN Speed), WARNING
106
hw.sensors.aibs0.fan5=0 RPM (OPT4 FAN Speed), WARNING
107
hw.sensors.aibs0.fan6=0 RPM (OPT5 FAN Speed), WARNING
108
hw.sensors.aibs0.fan7=0 RPM (PWR FAN Speed), WARNING
109
hw.sensors.aibs0.volt0=1.26 VDC (Vcore Voltage), OK
110
hw.sensors.aibs0.volt1=3.25 VDC ( +3.3 Voltage), OK
111
hw.sensors.aibs0.volt2=4.95 VDC ( +5.0 Voltage), OK
112
hw.sensors.aibs0.volt3=11.78 VDC (+12.0 Voltage), OK
113
hw.sensors.aibs0.volt4=1.23 VDC (1.2VHT Voltage), OK
114
hw.sensors.aibs0.volt5=1.50 VDC (SB CORE Voltage), OK
115
hw.sensors.aibs0.volt6=1.25 VDC (CPU VTT Voltage), OK
116
hw.sensors.aibs0.volt7=0.93 VDC (DDR2 TERM Voltage), OK
117
hw.sensors.aibs0.volt8=1.23 VDC (NB CORE Voltage), OK
118
hw.sensors.aibs0.volt9=1.87 VDC (MEMORY Voltage), OK
119
.Ed
120
.Pp
121
Generally, sensors provided by the
122
.Nm
123
driver may also be supported by a variety of other drivers,
124
such as
125
.Xr lm 4
126
or
127
.Xr it 4 .
128
The precise collection of
129
.Nm
130
sensors is comprised of the sensors
131
specifically utilised in the motherboard
132
design, which may be supported through
133
a combination of one or more physical hardware monitoring chips.
134
.Pp
135
The
136
.Nm
137
driver, however, provides the following advantages
138
when compared to the native hardware monitoring drivers:
139
.Bl -bullet
140
.It
141
Sensor values from
142
.Nm
143
are expected to be more reliable.
144
For example, voltage sensors in many hardware monitoring chips
145
can only sense voltage from 0 to 2 or 4 volts, and the excessive
146
voltage is removed by the resistors, which may vary with the motherboard
147
and with the voltage that is being sensed.
148
In
149
.Nm ,
150
the required resistor factors are provided by
151
the motherboard manufacturer through ACPI;
152
in the native drivers, the resistor factors
153
are encoded into the driver based on the chip manufacturer's recommendations.
154
In essence, sensor values from
155
.Nm
156
are very likely to be identical to the readings from the
157
Hardware Monitor screen in the BIOS.
158
.It
159
Sensor descriptions from
160
.Nm
161
are more likely to match the markings on the motherboard.
162
.It
163
Sensor status is supported by
164
.Nm .
165
The status is reported based on the acceptable range of values
166
for each individual sensor as suggested by the motherboard manufacturer.
167
For example, the threshold for the CPU temperature sensor is likely
168
to be significantly higher than that for the chassis temperature sensor.
169
.It
170
Support for newer chips in
171
.Nm .
172
Newer chips may miss a native driver,
173
but should be supported through
174
.Nm
175
regardless.
176
.El
177
.Pp
178
As a result, sensor readings from the actual
179
native hardware monitoring drivers
180
are redundant when
181
.Nm
182
is present, and
183
may be ignored as appropriate.
184
Whereas on
185
.Ox
186
the native drivers have to be specifically disabled should
187
their presence be judged unnecessary,
188
on
189
.Dx
190
the
191
.Xr lm 4
192
and
193
.Xr it 4
194
are not probed provided that
195
.Xr acpi 4
196
is configured and the system potentially supports
197
the hardware monitoring chip through ACPI.
198
.Sh SEE ALSO
199
.Xr systat 1 ,
200
.Xr sysctl 3 ,
201
.Xr acpi 4 ,
202
.Xr intro 4 ,
203
.Xr sensorsd 8 ,
204
.Xr sysctl 8
205
.Sh HISTORY
206
The
207
.Nm
208
driver first appeared in
209
.Ox 4.7
210
and
211
.Dx 2.5 .
212
.Sh AUTHORS
213
The
214
.Nm
215
driver was written for
216
.Ox
217
and
218
.Dx
219
by
220
.An Constantine A. Murenin Aq http://cnst.su/ ,
221
David R. Cheriton School of Computer Science,
222
University of Waterloo.
sys/conf/files
1712 1712
${OSACPI_MI_DIR}/acpi_toshiba/acpi_toshiba.c	optional acpi_toshiba acpi
1713 1713
${OSACPI_MI_DIR}/acpi_thinkpad/acpi_thinkpad.c	optional acpi_thinkpad acpi
1714 1714
${OSACPI_MI_DIR}/acpi_video/acpi_video.c	optional acpi_video acpi
1715
${OSACPI_MI_DIR}/aibs/atk0110.c			optional aibs acpi
1715 1716

  
1716 1717
# ACPICA code
1717 1718
${ACPICA_DIR}/debugger/dbcmds.c			optional acpi acpi_debug
sys/config/LINT
2663 2663
device		acpi_thinkpad	# ThinkPad support
2664 2664
device		acpi_toshiba	# Toshiba laptop support
2665 2665
device		acpi_video	# ACPI video extensions
2666
device		aibs		# ASUSTeK AI Booster (ACPI ASOC ATK0110)
2666 2667
device		pmtimer		# adjust the system clock after resume
2667 2668

  
2668 2669
# DRM options:
sys/dev/acpica5/Makefile
115 115
	${MAKE} -f ${SYSDIR}/${OSACPI_MD_DIR}/Makefile \
116 116
		MAKESRCPATH=${SYSDIR}/${OSACPI_MD_DIR}
117 117

  
118
SUBDIR=	acpi_asus acpi_thinkpad acpi_toshiba acpi_video
118
SUBDIR=	acpi_asus acpi_thinkpad acpi_toshiba acpi_video aibs
119 119
all: ${PROG} ${SUBDIR}
120 120

  
121 121
.include <bsd.kmod.mk>
sys/dev/acpica5/aibs/Makefile
1
KMOD=		aibs
2
CFLAGS+=	-I${.OBJDIR}/.. -I${.CURDIR}/..
3
SRCS=		atk0110.c
4
SRCS+=		opt_acpi.h bus_if.h device_if.h
5

  
6
.include <bsd.kmod.mk>
sys/dev/acpica5/aibs/atk0110.c
1
/*	$OpenBSD: atk0110.c,v 1.1 2009/07/23 01:38:16 cnst Exp $	*/
2

  
3
/*
4
 * Copyright (c) 2009 Constantine A. Murenin <cnst+dfly@bugmail.mojo.ru>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18

  
19
#include <sys/cdefs.h>
20
#include <sys/param.h>
21
#include <sys/systm.h>
22
#include <sys/kernel.h>
23
#include <sys/bus.h>
24
#include <sys/module.h>
25
#include <sys/malloc.h>
26

  
27
#include <sys/sensors.h>
28

  
29
#include "acpi.h"
30
#include "acpivar.h"
31

  
32
/*
33
 * ASUSTeK AI Booster (ACPI ATK0110).
34
 *
35
 * This code was originally written for OpenBSD after the techniques
36
 * described in the Linux's asus_atk0110.c and FreeBSD's acpi_aiboost.c
37
 * were verified to be accurate on the actual hardware kindly provided by
38
 * Sam Fourman Jr.  It was subsequently ported from OpenBSD to DragonFly BSD.
39
 *
40
 *				  -- Constantine A. Murenin <http://cnst.su/>
41
 */
42

  
43
#define AIBS_MORE_SENSORS
44
#define AIBS_VERBOSE
45

  
46
struct aibs_sensor {
47
	struct ksensor	s;
48
	int64_t		i;
49
	int64_t		l;
50
	int64_t		h;
51
};
52

  
53
struct aibs_softc {
54
	struct device		*sc_dev;
55
	ACPI_HANDLE		sc_ah;
56

  
57
	struct aibs_sensor	*sc_asens_volt;
58
	struct aibs_sensor	*sc_asens_temp;
59
	struct aibs_sensor	*sc_asens_fan;
60

  
61
	struct ksensordev	sc_sensordev;
62
};
63

  
64

  
65
static int aibs_probe(struct device *);
66
static int aibs_attach(struct device *);
67
static int aibs_detach(struct device *);
68
static void aibs_refresh(void *);
69

  
70
static void aibs_attach_sif(struct aibs_softc *, enum sensor_type);
71
static void aibs_refresh_r(struct aibs_softc *, enum sensor_type);
72

  
73

  
74
static device_method_t aibs_methods[] = {
75
	DEVMETHOD(device_probe,		aibs_probe),
76
	DEVMETHOD(device_attach,	aibs_attach),
77
	DEVMETHOD(device_detach,	aibs_detach),
78
	{ NULL, NULL }
79
};
80

  
81
static driver_t aibs_driver = {
82
	"aibs",
83
	aibs_methods,
84
	sizeof(struct aibs_softc)
85
};
86

  
87
static devclass_t aibs_devclass;
88

  
89
DRIVER_MODULE(aibs, acpi, aibs_driver, aibs_devclass, NULL, NULL);
90

  
91

  
92
static char* aibs_hids[] = {
93
	"ATK0110",
94
	NULL
95
};
96

  
97
static int
98
aibs_probe(struct device *dev)
99
{
100

  
101
	if (acpi_disabled("aibs") ||
102
	    ACPI_ID_PROBE(device_get_parent(dev), dev, aibs_hids) == NULL)
103
		return ENXIO;
104

  
105
	device_set_desc(dev, "ASUSTeK AI Booster (ACPI ASOC ATK0110)");
106
	return 0;
107
}
108

  
109
static int
110
aibs_attach(struct device *dev)
111
{
112
	struct aibs_softc	*sc;
113

  
114
	sc = device_get_softc(dev);
115
	sc->sc_dev = dev;
116
	sc->sc_ah = acpi_get_handle(dev);
117

  
118
	strlcpy(sc->sc_sensordev.xname, device_get_nameunit(dev),
119
	    sizeof(sc->sc_sensordev.xname));
120

  
121
	aibs_attach_sif(sc, SENSOR_VOLTS_DC);
122
	aibs_attach_sif(sc, SENSOR_TEMP);
123
	aibs_attach_sif(sc, SENSOR_FANRPM);
124

  
125
	if (sc->sc_sensordev.sensors_count == 0) {
126
		device_printf(dev, "no sensors found\n");
127
		return ENXIO;
128
	}
129

  
130
	if (sensor_task_register(sc, aibs_refresh, 5)) {
131
		device_printf(dev, "unable to register update task\n");
132
		return ENXIO;
133
	}
134

  
135
	sensordev_install(&sc->sc_sensordev);
136
	return 0;
137
}
138

  
139
static void
140
aibs_attach_sif(struct aibs_softc *sc, enum sensor_type st)
141
{
142
	ACPI_STATUS		s;
143
	ACPI_BUFFER		b;
144
	ACPI_OBJECT		*bp, *o;
145
	int			i, n;
146
	char			name[] = "?SIF";
147
	struct aibs_sensor	*as;
148

  
149
	switch (st) {
150
	case SENSOR_TEMP:
151
		name[0] = 'T';
152
		break;
153
	case SENSOR_FANRPM:
154
		name[0] = 'F';
155
		break;
156
	case SENSOR_VOLTS_DC:
157
		name[0] = 'V';
158
		break;
159
	default:
160
		return;
161
	}
162

  
163
	b.Length = ACPI_ALLOCATE_BUFFER;
164
	s = AcpiEvaluateObjectTyped(sc->sc_ah, name, NULL, &b,
165
	    ACPI_TYPE_PACKAGE);
166
	if (ACPI_FAILURE(s)) {
167
		device_printf(sc->sc_dev, "%s not found\n", name);
168
		return;
169
	}
170

  
171
	bp = b.Pointer;
172
	o = bp->Package.Elements;
173
	if (o[0].Type != ACPI_TYPE_INTEGER) {
174
		device_printf(sc->sc_dev, "%s[0]: invalid type\n", name);
175
		AcpiOsFree(b.Pointer);
176
		return;
177
	}
178

  
179
	n = o[0].Integer.Value;
180
	if (bp->Package.Count - 1 < n) {
181
		device_printf(sc->sc_dev, "%s: invalid package\n", name);
182
		AcpiOsFree(b.Pointer);
183
		return;
184
	} else if (bp->Package.Count - 1 > n) {
185
		int on = n;
186

  
187
#ifdef AIBS_MORE_SENSORS
188
		n = bp->Package.Count - 1;
189
#endif
190
		device_printf(sc->sc_dev, "%s: misformed package: %i/%i"
191
		    ", assume %i\n", name, on, bp->Package.Count - 1, n);
192
	}
193
	if (n < 1) {
194
		device_printf(sc->sc_dev, "%s: no members in the package\n",
195
		    name);
196
		AcpiOsFree(b.Pointer);
197
		return;
198
	}
199

  
200
	as = kmalloc(sizeof(*as) * n, M_DEVBUF, M_NOWAIT | M_ZERO);
201
	if (as == NULL) {
202
		device_printf(sc->sc_dev, "%s: malloc fail\n", name);
203
		AcpiOsFree(b.Pointer);
204
		return;
205
	}
206

  
207
	switch (st) {
208
	case SENSOR_TEMP:
209
		sc->sc_asens_temp = as;
210
		break;
211
	case SENSOR_FANRPM:
212
		sc->sc_asens_fan = as;
213
		break;
214
	case SENSOR_VOLTS_DC:
215
		sc->sc_asens_volt = as;
216
		break;
217
	default:
218
		/* NOTREACHED */
219
		return;
220
	}
221

  
222
	for (i = 0, o++; i < n; i++, o++) {
223
		ACPI_OBJECT	*oi;
224

  
225
		/* acpica5 automatically evaluates the referenced package */
226
		if(o[0].Type != ACPI_TYPE_PACKAGE) {
227
			device_printf(sc->sc_dev,
228
			    "%s: %i: not a package: %i type\n",
229
			    name, i, o[0].Type);
230
			continue;
231
		}
232
		oi = o[0].Package.Elements;
233
		if (o[0].Package.Count != 5 ||
234
		    oi[0].Type != ACPI_TYPE_INTEGER ||
235
		    oi[1].Type != ACPI_TYPE_STRING ||
236
		    oi[2].Type != ACPI_TYPE_INTEGER ||
237
		    oi[3].Type != ACPI_TYPE_INTEGER ||
238
		    oi[4].Type != ACPI_TYPE_INTEGER) {
239
			device_printf(sc->sc_dev,
240
			    "%s: %i: invalid package\n",
241
			    name, i);
242
			continue;
243
		}
244
		as[i].i = oi[0].Integer.Value;
245
		strlcpy(as[i].s.desc, oi[1].String.Pointer,
246
		    sizeof(as[i].s.desc));
247
		as[i].l = oi[2].Integer.Value;
248
		as[i].h = oi[3].Integer.Value;
249
		as[i].s.type = st;
250
#ifdef AIBS_VERBOSE
251
		device_printf(sc->sc_dev, "%c%i: "
252
		    "0x%08llx %20s %5lli / %5lli  0x%llx\n",
253
		    name[0], i,
254
		    as[i].i, as[i].s.desc, as[i].l, as[i].h,
255
		    oi[4].Integer.Value);
256
#endif
257
		sensor_attach(&sc->sc_sensordev, &as[i].s);
258
	}
259

  
260
	AcpiOsFree(b.Pointer);
261
	return;
262
}
263

  
264
static int
265
aibs_detach(struct device *dev)
266
{
267
	struct aibs_softc	*sc = device_get_softc(dev);
268

  
269
	sensordev_deinstall(&sc->sc_sensordev);
270
	sensor_task_unregister(sc);
271
	if (sc->sc_asens_volt != NULL)
272
		kfree(sc->sc_asens_volt, M_DEVBUF);
273
	if (sc->sc_asens_temp != NULL)
274
		kfree(sc->sc_asens_temp, M_DEVBUF);
275
	if (sc->sc_asens_fan != NULL)
276
		kfree(sc->sc_asens_fan, M_DEVBUF);
277
	return 0;
278
}
279

  
280
#ifdef AIBS_VERBOSE
281
#define ddevice_printf(x...) device_printf(x)
282
#else
283
#define ddevice_printf(x...)
284
#endif
285

  
286
static void
287
aibs_refresh(void *arg)
288
{
289
	struct aibs_softc *sc = arg;
290

  
291
	aibs_refresh_r(sc, SENSOR_VOLTS_DC);
292
	aibs_refresh_r(sc, SENSOR_TEMP);
293
	aibs_refresh_r(sc, SENSOR_FANRPM);
294
}
295

  
296
static void
297
aibs_refresh_r(struct aibs_softc *sc, enum sensor_type st)
298
{
299
	ACPI_STATUS		rs;
300
	ACPI_HANDLE		rh;
301
	int			i, n = sc->sc_sensordev.maxnumt[st];
302
	char			*name;
303
	struct aibs_sensor	*as;
304

  
305
	switch (st) {
306
	case SENSOR_TEMP:
307
		name = "RTMP";
308
		as = sc->sc_asens_temp;
309
		break;
310
	case SENSOR_FANRPM:
311
		name = "RFAN";
312
		as = sc->sc_asens_fan;
313
		break;
314
	case SENSOR_VOLTS_DC:
315
		name = "RVLT";
316
		as = sc->sc_asens_volt;
317
		break;
318
	default:
319
		return;
320
	}
321

  
322
	if (as == NULL)
323
		return;
324

  
325
	rs = AcpiGetHandle(sc->sc_ah, name, &rh);
326
	if (ACPI_FAILURE(rs)) {
327
		ddevice_printf(sc->sc_dev, "%s: method handle not found\n",
328
		    name);
329
		for (i = 0; i < n; i++)
330
			as[i].s.flags |= SENSOR_FINVALID;
331
		return;
332
	}
333

  
334
	for (i = 0; i < n; i++) {
335
		ACPI_OBJECT		p, *bp;
336
		ACPI_OBJECT_LIST	mp;
337
		ACPI_BUFFER		b;
338
		int64_t			v;
339
		struct ksensor		*s = &as[i].s;
340
		const int64_t		l = as[i].l, h = as[i].h;
341

  
342
		p.Type = ACPI_TYPE_INTEGER;
343
		p.Integer.Value = as[i].i;
344
		mp.Count = 1;
345
		mp.Pointer = &p;
346
		b.Length = ACPI_ALLOCATE_BUFFER;
347
		rs = AcpiEvaluateObjectTyped(rh, NULL, &mp, &b,
348
		    ACPI_TYPE_INTEGER);
349
		if (ACPI_FAILURE(rs)) {
350
			ddevice_printf(sc->sc_dev,
351
			    "%s: %i: evaluation failed\n",
352
			    name, i);
353
			s->flags |= SENSOR_FINVALID;
354
			continue;
355
		}
356
		bp = b.Pointer;
357
		v = bp->Integer.Value;
358
		AcpiOsFree(b.Pointer);
359

  
360
		switch (st) {
361
		case SENSOR_TEMP:
362
			s->value = v * 100 * 1000 + 273150000;
363
			if (v == 0) {
364
				s->status = SENSOR_S_UNKNOWN;
365
				s->flags |= SENSOR_FINVALID;
366
			} else {
367
				if (v > h)
368
					s->status = SENSOR_S_CRIT;
369
				else if (v > l)
370
					s->status = SENSOR_S_WARN;
371
				else
372
					s->status = SENSOR_S_OK;
373
				s->flags &= ~SENSOR_FINVALID;
374
			}
375
			break;
376
		case SENSOR_FANRPM:
377
			s->value = v;
378
			/* some boards have strange limits for fans */
379
			if ((l != 0 && l < v && v < h) ||
380
			    (l == 0 && v > h))
381
				s->status = SENSOR_S_OK;
382
			else
383
				s->status = SENSOR_S_WARN;
384
			s->flags &= ~SENSOR_FINVALID;
385
			break;
386
		case SENSOR_VOLTS_DC:
387
			s->value = v * 1000;
388
			if (l < v && v < h)
389
				s->status = SENSOR_S_OK;
390
			else
391
				s->status = SENSOR_S_WARN;
392
			s->flags &= ~SENSOR_FINVALID;
393
			break;
394
		default:
395
			/* NOTREACHED */
396
			break;
397
		}
398
	}
399

  
400
	return;
401
}
0
-