Module Name:    src
Committed By:   hannken
Date:           Mon Feb 14 08:50:40 UTC 2011

Modified Files:
        src/distrib/sets/lists/man: mi
        src/share/man/man4: Makefile
        src/sys/arch/amd64/conf: GENERIC
        src/sys/arch/i386/conf: ALL GENERIC
        src/sys/dev/i2c: files.i2c
Added Files:
        src/share/man/man4: ibmhawk.4
        src/sys/dev/i2c: ibmhawk.c ibmhawkreg.h ibmhawkvar.h

Log Message:
Initial implementation of ibmhawk(4) driver for sensors behind the IBM Hawk
on-board Integrated Systems Management Processor found on some eServers.

Tested on an IBM eServer x335.


To generate a diff of this commit:
cvs rdiff -u -r1.1287 -r1.1288 src/distrib/sets/lists/man/mi
cvs rdiff -u -r1.549 -r1.550 src/share/man/man4/Makefile
cvs rdiff -u -r0 -r1.1 src/share/man/man4/ibmhawk.4
cvs rdiff -u -r1.303 -r1.304 src/sys/arch/amd64/conf/GENERIC
cvs rdiff -u -r1.286 -r1.287 src/sys/arch/i386/conf/ALL
cvs rdiff -u -r1.1013 -r1.1014 src/sys/arch/i386/conf/GENERIC
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/i2c/files.i2c
cvs rdiff -u -r0 -r1.1 src/sys/dev/i2c/ibmhawk.c src/sys/dev/i2c/ibmhawkreg.h \
    src/sys/dev/i2c/ibmhawkvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/man/mi
diff -u src/distrib/sets/lists/man/mi:1.1287 src/distrib/sets/lists/man/mi:1.1288
--- src/distrib/sets/lists/man/mi:1.1287	Thu Feb 10 14:04:30 2011
+++ src/distrib/sets/lists/man/mi	Mon Feb 14 08:50:38 2011
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1287 2011/02/10 14:04:30 rmind Exp $
+# $NetBSD: mi,v 1.1288 2011/02/14 08:50:38 hannken Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -1130,6 +1130,7 @@
 ./usr/share/man/cat4/i4btrc.0			man-obsolete		obsolete
 ./usr/share/man/cat4/i915drm.0			man-sys-catman		.cat
 ./usr/share/man/cat4/iavc.0			man-sys-catman		.cat
+./usr/share/man/cat4/ibmhawk.0			man-sys-catman		.cat
 ./usr/share/man/cat4/ichlpcib.0			man-obsolete		obsolete
 ./usr/share/man/cat4/ichsmb.0			man-sys-catman		.cat
 ./usr/share/man/cat4/icmp.0			man-sys-catman		.cat
@@ -3860,6 +3861,7 @@
 ./usr/share/man/html4/i386/vesafb.html		man-obsolete		obsolete
 ./usr/share/man/html4/i915drm.html		man-sys-htmlman		html
 ./usr/share/man/html4/iavc.html			man-sys-htmlman		html
+./usr/share/man/html4/ibmhawk.html		man-sys-htmlman		html
 ./usr/share/man/html4/ichlpcib.html		man-obsolete		obsolete
 ./usr/share/man/html4/ichsmb.html		man-sys-htmlman		html
 ./usr/share/man/html4/icmp.html			man-sys-htmlman		html
@@ -6425,6 +6427,7 @@
 ./usr/share/man/man4/i4btrc.4			man-obsolete		obsolete
 ./usr/share/man/man4/i915drm.4			man-sys-man		.man
 ./usr/share/man/man4/iavc.4			man-sys-man		.man
+./usr/share/man/man4/ibmhawk.4			man-sys-man		.man
 ./usr/share/man/man4/ichlpcib.4			man-obsolete		obsolete
 ./usr/share/man/man4/ichsmb.4			man-sys-man		.man
 ./usr/share/man/man4/icmp.4			man-sys-man		.man

Index: src/share/man/man4/Makefile
diff -u src/share/man/man4/Makefile:1.549 src/share/man/man4/Makefile:1.550
--- src/share/man/man4/Makefile:1.549	Wed Feb  9 15:31:30 2011
+++ src/share/man/man4/Makefile	Mon Feb 14 08:50:39 2011
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.549 2011/02/09 15:31:30 tsutsui Exp $
+#	$NetBSD: Makefile,v 1.550 2011/02/14 08:50:39 hannken Exp $
 #	@(#)Makefile	8.1 (Berkeley) 6/18/93
 
 MAN=	aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
@@ -28,7 +28,7 @@
 	gcscaudio.4 gem.4 genfb.4 gentbi.4 geodeide.4 \
 	glxtphy.4 gpib.4 gpio.4 gpiolock.4 gpiosim.4 gre.4 gphyter.4 gsip.4 \
 	hdaudio.4 hifn.4 hme.4 hpqlb.4 hptide.4 \
-	ichsmb.4 icmp.4 icp.4 icsphy.4 iee.4 ieee80211.4 \
+	ibmhawk.4 ichsmb.4 icmp.4 icp.4 icsphy.4 iee.4 ieee80211.4 \
 	ifmedia.4 igphy.4 igsfb.4 iha.4 ihphy.4 iic.4 inet.4 ikphy.4 inphy.4 \
 	intersil7170.4 \
 	ioasic.4 ioat.4 iop.4 iophy.4 iopsp.4 ip.4 ipkdb.4 ipmi.4 ipw.4 \

Index: src/sys/arch/amd64/conf/GENERIC
diff -u src/sys/arch/amd64/conf/GENERIC:1.303 src/sys/arch/amd64/conf/GENERIC:1.304
--- src/sys/arch/amd64/conf/GENERIC:1.303	Sun Feb 13 04:21:23 2011
+++ src/sys/arch/amd64/conf/GENERIC	Mon Feb 14 08:50:39 2011
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.303 2011/02/13 04:21:23 jym Exp $
+# $NetBSD: GENERIC,v 1.304 2011/02/14 08:50:39 hannken Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident 		"GENERIC-$Revision: 1.303 $"
+#ident 		"GENERIC-$Revision: 1.304 $"
 
 maxusers	64		# estimated number of users
 
@@ -428,6 +428,9 @@
 #wbsio*	at isa? port 0x2e
 #wbsio*	at isa? port 0x4e
 
+# IBM Hawk Integrated Systems Management Processor
+#ibmhawk0	at iic? addr 0x37
+
 # LM7[89] and compatible hardware monitors
 # Use flags to select temp sensor type (see lm(4) man page for details)
 #lm0	at isa?	port 0x290 flags 0x0	# other common ports: 0x280, 0x310

Index: src/sys/arch/i386/conf/ALL
diff -u src/sys/arch/i386/conf/ALL:1.286 src/sys/arch/i386/conf/ALL:1.287
--- src/sys/arch/i386/conf/ALL:1.286	Fri Feb 11 01:59:56 2011
+++ src/sys/arch/i386/conf/ALL	Mon Feb 14 08:50:39 2011
@@ -1,4 +1,4 @@
-# $NetBSD: ALL,v 1.286 2011/02/11 01:59:56 jmcneill Exp $
+# $NetBSD: ALL,v 1.287 2011/02/14 08:50:39 hannken Exp $
 # From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
 #
 # ALL machine description file
@@ -17,7 +17,7 @@
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident 		"ALL-$Revision: 1.286 $"
+#ident 		"ALL-$Revision: 1.287 $"
 
 maxusers	64		# estimated number of users
 
@@ -708,6 +708,9 @@
 dbcool* at iic? addr 0x2D		# Tyan S2881
 dbcool* at iic? addr 0x2E		# Tyan S2882-D
 
+# IBM Hawk Integrated Systems Management Processor
+ibmhawk0	at iic?	addr 0x37
+
 # LM7[89] and compatible hardware monitors
 # Use flags to select temp sensor type (see lm(4) man page for details)
 lm0	at iic?	addr 0x2e flags 0x0

Index: src/sys/arch/i386/conf/GENERIC
diff -u src/sys/arch/i386/conf/GENERIC:1.1013 src/sys/arch/i386/conf/GENERIC:1.1014
--- src/sys/arch/i386/conf/GENERIC:1.1013	Sun Feb 13 04:37:21 2011
+++ src/sys/arch/i386/conf/GENERIC	Mon Feb 14 08:50:39 2011
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.1013 2011/02/13 04:37:21 jym Exp $
+# $NetBSD: GENERIC,v 1.1014 2011/02/14 08:50:39 hannken Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident 		"GENERIC-$Revision: 1.1013 $"
+#ident 		"GENERIC-$Revision: 1.1014 $"
 
 maxusers	64		# estimated number of users
 
@@ -678,6 +678,9 @@
 #wbsio*	at isa? port 0x2e
 #wbsio*	at isa? port 0x4e
 
+# IBM Hawk Integrated Systems Management Processor
+#ibmhawk0	at iic?	addr 0x37
+
 # LM7[89] and compatible hardware monitors
 # Use flags to select temp sensor type (see lm(4) man page for details)
 #lm0	at isa?	port 0x290 flags 0x0	# other common: 0x280, 0x310

Index: src/sys/dev/i2c/files.i2c
diff -u src/sys/dev/i2c/files.i2c:1.32 src/sys/dev/i2c/files.i2c:1.33
--- src/sys/dev/i2c/files.i2c:1.32	Fri Jan 21 19:11:47 2011
+++ src/sys/dev/i2c/files.i2c	Mon Feb 14 08:50:39 2011
@@ -1,4 +1,4 @@
-#	$NetBSD: files.i2c,v 1.32 2011/01/21 19:11:47 jakllsch Exp $
+#	$NetBSD: files.i2c,v 1.33 2011/02/14 08:50:39 hannken Exp $
 
 defflag	opt_i2cbus.h				I2C_SCAN
 define	i2cbus { }
@@ -145,3 +145,8 @@
 device	g760a: sysmon_envsys
 attach	g760a at iic
 file	dev/i2c/g760a.c			g760a
+
+# IBM Hawk Integrated Systems Management Processor
+device	ibmhawk: sysmon_envsys
+attach	ibmhawk at iic
+file	dev/i2c/ibmhawk.c		ibmhawk

Added files:

Index: src/share/man/man4/ibmhawk.4
diff -u /dev/null src/share/man/man4/ibmhawk.4:1.1
--- /dev/null	Mon Feb 14 08:50:40 2011
+++ src/share/man/man4/ibmhawk.4	Mon Feb 14 08:50:39 2011
@@ -0,0 +1,58 @@
+.\" $NetBSD: ibmhawk.4,v 1.1 2011/02/14 08:50:39 hannken Exp $
+.\"
+.\" Copyright (c) 2011 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Juergen Hannken-Illjes.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd February 14, 2011
+.Dt IBMHAWK 4
+.Os
+.Sh NAME
+.Nm ibmhawk
+.Nd IBM Hawk Integrated Systems Management Processor
+.Sh SYNOPSUS
+.Cd "ibmhawk0 at iic?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the temperature, voltage and
+fan sensors present on IBM eServers equipped with an on-board
+Hawk Integrated Systems Management Processor.
+.Pp
+The
+.Nm
+driver reports these sensors through the
+.Xr envsys 4
+API.
+.Sh SEE ALSO
+.Xr envsys 4 ,
+.Xr envstat 8 ,
+.Xr powerd 8
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Nx 6.0 .

Index: src/sys/dev/i2c/ibmhawk.c
diff -u /dev/null src/sys/dev/i2c/ibmhawk.c:1.1
--- /dev/null	Mon Feb 14 08:50:40 2011
+++ src/sys/dev/i2c/ibmhawk.c	Mon Feb 14 08:50:39 2011
@@ -0,0 +1,386 @@
+/* $NetBSD: ibmhawk.c,v 1.1 2011/02/14 08:50:39 hannken Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/systm.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/bswap.h>
+
+#include <dev/sysmon/sysmonvar.h>
+#include <dev/i2c/i2cvar.h>
+#include <dev/i2c/ibmhawkreg.h>
+#include <dev/i2c/ibmhawkvar.h>
+
+#if !defined(IBMHAWK_DEBUG)	/* Set to 2 for verbose debug. */
+#if defined(DEBUG)
+#define IBMHAWK_DEBUG	1
+#else
+#define IBMHAWK_DEBUG	0
+#endif
+#endif
+
+/*
+ * Known sensors.
+ */
+static struct ibmhawk_sensordesc {
+	const char *desc;
+	uint32_t units;
+	int offset;
+} ibmhawk_sensors[] = {
+	{ "Ambient temperature", ENVSYS_STEMP,     IBMHAWK_T_AMBIENT   },
+	{ "CPU 1 temperature",   ENVSYS_STEMP,     IBMHAWK_T_CPU       },
+	{ "CPU 2 temperature",   ENVSYS_STEMP,     IBMHAWK_T_CPU+1     },
+	{ "12 Voltage sensor",   ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE   },
+	{ "5 Voltage sensor",    ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+1 },
+	{ "3.3 Voltage sensor",  ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+2 },
+	{ "2.5 Voltage sensor",  ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+3 },
+	{ "1.5 Voltage sensor",  ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+4 },
+	{ "1.25 Voltage sensor", ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+5 },
+	{ "VRM 1",               ENVSYS_SVOLTS_DC, IBMHAWK_V_VOLTAGE+6 },
+	{ "Fan 1",               ENVSYS_SFANRPM,   IBMHAWK_F_FAN       },
+	{ "Fan 2",               ENVSYS_SFANRPM,   IBMHAWK_F_FAN+1     },
+	{ "Fan 3",               ENVSYS_SFANRPM,   IBMHAWK_F_FAN+2     },
+	{ "Fan 4",               ENVSYS_SFANRPM,   IBMHAWK_F_FAN+3     },
+	{ "Fan 5",               ENVSYS_SFANRPM,   IBMHAWK_F_FAN+4     },
+	{ "Fan 6",               ENVSYS_SFANRPM,   IBMHAWK_F_FAN+5     },
+};
+static const int ibmhawk_num_sensors =
+    (sizeof(ibmhawk_sensors)/sizeof(ibmhawk_sensors[0]));
+
+static int ibmhawk_match(device_t, cfdata_t, void *);
+static void ibmhawk_attach(device_t, device_t, void *);
+static int ibmhawk_detach(device_t, int);
+static uint8_t ibmhawk_cksum(uint8_t *);
+static int ibmhawk_request(struct ibmhawk_softc *,
+    uint8_t, ibmhawk_response_t *);
+static uint32_t ibmhawk_normalize(int, uint32_t);
+static void ibmhawk_set(struct ibmhawk_softc *, int, int, bool, bool);
+static void ibmhawk_refreshall(struct ibmhawk_softc *, bool);
+static void ibmhawk_refresh(struct sysmon_envsys *, envsys_data_t *);
+static void ibmhawk_get_limits(struct sysmon_envsys *, envsys_data_t *,
+    sysmon_envsys_lim_t *, uint32_t *);
+
+CFATTACH_DECL_NEW(ibmhawk, sizeof(struct ibmhawk_softc),
+    ibmhawk_match, ibmhawk_attach, ibmhawk_detach, NULL);
+
+static int
+ibmhawk_match(device_t parent, cfdata_t match, void *aux)
+{
+	struct i2c_attach_args *ia = aux;
+	ibmhawk_response_t resp;
+	static struct ibmhawk_softc sc;
+
+	sc.sc_tag = ia->ia_tag;
+	sc.sc_addr = ia->ia_addr;
+	if (ibmhawk_request(&sc, IHR_EQUIP, &resp))
+		return 0;
+	return 1;
+}
+
+static void
+ibmhawk_attach(device_t parent, device_t self, void *aux)
+{
+	struct ibmhawk_softc *sc = device_private(self);
+	struct i2c_attach_args *ia = aux;
+	ibmhawk_response_t resp;
+	int i;
+
+	sc->sc_dev = self;
+	sc->sc_tag = ia->ia_tag;
+	sc->sc_addr = ia->ia_addr;
+
+	if (!pmf_device_register(self, NULL, NULL))
+		aprint_error_dev(self, "couldn't establish power handler\n");
+	if (ibmhawk_request(sc, IHR_NAME, &resp)) {
+		aprint_normal(": communication failed\n");
+		return;
+	}
+	aprint_normal(": IBM Hawk \"%.16s\"\n", resp.ihr_name);
+	if (ibmhawk_request(sc, IHR_EQUIP, &resp)) {
+		aprint_error_dev(sc->sc_dev, "equip query failed\n");
+		return;
+	}
+	sc->sc_numcpus = min(resp.ihr_numcpus, IBMHAWK_MAX_CPU);
+	sc->sc_numfans = min(resp.ihr_numfans, IBMHAWK_MAX_FAN);
+#if IBMHAWK_DEBUG > 0
+	aprint_normal_dev(sc->sc_dev, "monitoring %d/%d cpu(s) %d/%d fan(s)\n",
+	    sc->sc_numcpus, resp.ihr_numcpus, sc->sc_numfans, resp.ihr_numfans);
+#endif
+	/* Request and set sensor thresholds. */
+	if (ibmhawk_request(sc, IHR_TEMP_THR, &resp)) {
+		aprint_error_dev(sc->sc_dev, "temp threshold query failed\n");
+		return;
+	}
+	for (i = 0; i < sc->sc_numcpus; i++)
+		sc->sc_sensordata[IBMHAWK_T_CPU+i].ihs_warnmax =
+		    resp.ihr_t_warn_thr;
+	if (ibmhawk_request(sc, IHR_VOLT_THR, &resp)) {
+		aprint_error_dev(sc->sc_dev, "volt threshold query failed\n");
+		return;
+	}
+	for (i = 0; i < IBMHAWK_MAX_VOLTAGE; i++) {
+		sc->sc_sensordata[IBMHAWK_V_VOLTAGE+i].ihs_warnmax =
+		    bswap16(resp.ihr_v_voltage_thr[i*2]);
+		sc->sc_sensordata[IBMHAWK_V_VOLTAGE+i].ihs_warnmin =
+		    bswap16(resp.ihr_v_voltage_thr[i*2+1]);
+	}
+	if ((sc->sc_sme = sysmon_envsys_create()) == NULL) {
+		aprint_error_dev(sc->sc_dev, "sysmon_envsys_create failed\n");
+		return;
+	}
+	ibmhawk_refreshall(sc, true);
+	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
+	sc->sc_sme->sme_cookie = sc;
+	sc->sc_sme->sme_refresh = ibmhawk_refresh;
+	sc->sc_sme->sme_get_limits = ibmhawk_get_limits;
+	if (sysmon_envsys_register(sc->sc_sme)) {
+		aprint_error_dev(sc->sc_dev, "sysmon_envsys_register failed\n");
+		sysmon_envsys_destroy(sc->sc_sme);
+		sc->sc_sme = NULL;
+		return;
+	}
+}
+
+static int
+ibmhawk_detach(device_t self, int flags)
+{
+	struct ibmhawk_softc *sc = device_private(self);
+
+	if (sc->sc_sme)
+		sysmon_envsys_destroy(sc->sc_sme);
+	return 0;
+}
+
+
+/*
+ * Compute the message checksum.
+ */
+static uint8_t
+ibmhawk_cksum(uint8_t *buf)
+{
+	int len = *buf++;
+	int s = 0;
+
+	while (--len > 0)
+		s += *buf++;
+	return -s;
+}
+
+/*
+ * Request information from the management processor.
+ * The response will be zeroed on error.
+ * Request and response have the form <n> <data 0:n-2> <checksum>.
+ */
+static int
+ibmhawk_request(struct ibmhawk_softc *sc, uint8_t request,
+    ibmhawk_response_t *response)
+{
+	int i, error, retries;;
+	uint8_t buf[sizeof(ibmhawk_response_t)+3], dummy;
+
+	error = EIO;	/* Fail until we have a valid response. */
+	retries = 0;
+
+	if (iic_acquire_bus(sc->sc_tag, 0))
+		return error;
+
+again:
+	memset(response, 0, sizeof(*response));
+
+	/* Build and send the request. */
+	buf[0] = 2;
+	buf[1] = request;
+	buf[2] = ibmhawk_cksum(buf);
+#if IBMHAWK_DEBUG > 1
+	printf("[");
+	for (i = 0; i < 3; i++)
+		printf(" %02x", buf[i]);
+	printf(" ]");
+#endif
+	for (i = 0; i < 3; i++)
+		if (iic_smbus_send_byte(sc->sc_tag, sc->sc_addr, buf[i], 0))
+			goto bad;
+
+	/* Receive and check the response. */
+#if IBMHAWK_DEBUG > 1
+	printf(" => [");
+#endif
+	if (iic_smbus_receive_byte(sc->sc_tag, sc->sc_addr, &buf[0], 0))
+		goto bad;
+	if (buf[0] == 0 || buf[0] == 255)
+		goto bad;
+	for (i = 1; i < buf[0]+1; i++)
+		if (iic_smbus_receive_byte(sc->sc_tag, sc->sc_addr,
+		    (i < sizeof buf ? &buf[i] : &dummy), 0))
+			goto bad;
+	if (buf[0] >= sizeof(buf) || buf[1] != request ||
+	    ibmhawk_cksum(buf) != buf[buf[0]])
+		goto bad;
+	if (buf[0] > 2)
+		memcpy(response, buf+2, buf[0]-2);
+	error = 0;
+
+bad:
+#if IBMHAWK_DEBUG > 1
+	for (i = 0; i < min(buf[0]+1, sizeof buf); i++)
+		printf(" %02x", buf[i]);
+	printf(" ] => %d\n", error);
+#endif
+	if (error != 0 && retries++ < 3)
+		goto again;
+
+	iic_release_bus(sc->sc_tag, 0);
+	return error;
+}
+
+static uint32_t
+ibmhawk_normalize(int value, uint32_t units)
+{
+
+	if (value == 0)
+		return 0;
+
+	switch (units) {
+	case ENVSYS_STEMP:
+		return 273150000+1000000*value;
+	case ENVSYS_SVOLTS_DC:
+		return 10000*value;
+	default:
+		return value;
+	}
+}
+
+static void
+ibmhawk_set(struct ibmhawk_softc *sc,
+    int offset, int value, bool valid, bool create)
+{
+	int i;
+	struct ibmhawk_sensordesc *sp;
+	struct ibmhawk_sensordata *sd;
+	envsys_data_t *dp;
+
+	sd = &sc->sc_sensordata[offset];
+	dp = &sd->ihs_edata;
+	sp = NULL;
+	if (create) {
+		for (i = 0; i < ibmhawk_num_sensors; i++)
+			if (ibmhawk_sensors[i].offset == offset) {
+				sp = ibmhawk_sensors+i;
+				break;
+			}
+		if (sp == NULL) {
+#if IBMHAWK_DEBUG > 0
+			aprint_error_dev(sc->sc_dev,
+			    "offset %d: no sensor found\n", offset);
+#endif
+			return;
+		}
+		strlcpy(dp->desc, sp->desc, sizeof(dp->desc));
+		dp->units = sp->units;
+		if (sd->ihs_warnmin != 0 || sd->ihs_warnmax != 0) {
+			sd->ihs_warnmin =
+			    ibmhawk_normalize(sd->ihs_warnmin, dp->units);
+			sd->ihs_warnmax =
+			    ibmhawk_normalize(sd->ihs_warnmax, dp->units);
+			dp->flags |= ENVSYS_FMONLIMITS;
+		}
+		if (sysmon_envsys_sensor_attach(sc->sc_sme, dp))
+			aprint_error_dev(sc->sc_dev,
+			    "failed to attach \"%s\"\n", dp->desc);
+	}
+
+	dp->value_cur = ibmhawk_normalize(value, dp->units);
+	if (!valid)
+		dp->state = ENVSYS_SINVALID;
+	else if (sd->ihs_warnmin != 0 && value < sd->ihs_warnmin)
+		dp->state = ENVSYS_SWARNUNDER;
+	else if (sd->ihs_warnmax != 0 && value > sd->ihs_warnmax)
+		dp->state = ENVSYS_SWARNOVER;
+	else
+		dp->state = ENVSYS_SVALID;
+}
+
+static void
+ibmhawk_refreshall(struct ibmhawk_softc *sc, bool create)
+{
+	int i;
+	bool valid;
+	ibmhawk_response_t resp;
+
+	valid = (ibmhawk_request(sc, IHR_TEMP, &resp) == 0);
+	ibmhawk_set(sc, IBMHAWK_T_AMBIENT, resp.ihr_t_ambient, valid, create);
+	for (i = 0; i < sc->sc_numcpus; i++)
+		ibmhawk_set(sc, IBMHAWK_T_CPU+i,
+		    resp.ihr_t_cpu[i], valid, create);
+
+	valid = (ibmhawk_request(sc, IHR_FANRPM, &resp) == 0);
+	for (i = 0; i < sc->sc_numfans; i++)
+		ibmhawk_set(sc, IBMHAWK_F_FAN+i,
+		    bswap16(resp.ihr_fanrpm[i]), valid, create);
+
+	valid = (ibmhawk_request(sc, IHR_VOLT, &resp) == 0);
+	for (i = 0; i < IBMHAWK_MAX_VOLTAGE; i++)
+		ibmhawk_set(sc, IBMHAWK_V_VOLTAGE+i,
+		    bswap16(resp.ihr_v_voltage[i]), valid, create);
+}
+
+static void
+ibmhawk_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
+{
+	struct ibmhawk_softc *sc = sme->sme_cookie;
+
+	/* No more than two refreshes per second. */
+	if (hardclock_ticks-sc->sc_refresh < hz/2)
+		return;
+#if IBMHAWK_DEBUG > 1
+	aprint_normal_dev(sc->sc_dev, "refresh \"%s\" delta %d\n",
+	    edata->desc, hardclock_ticks-sc->sc_refresh);
+#endif
+	sc->sc_refresh = hardclock_ticks;
+	ibmhawk_refreshall(sc, false);
+}
+
+static void
+ibmhawk_get_limits(struct sysmon_envsys *sme, envsys_data_t *edata,
+    sysmon_envsys_lim_t *limits, uint32_t *props)
+{
+	struct ibmhawk_sensordata *sd = (struct ibmhawk_sensordata *)edata;
+
+	if (sd->ihs_warnmin != 0) {
+		limits->sel_warnmin = sd->ihs_warnmin;
+		*props |= PROP_WARNMIN;
+	}
+	if (sd->ihs_warnmax != 0) {
+		limits->sel_warnmax = sd->ihs_warnmax;
+		*props |= PROP_WARNMAX;
+	}
+}
Index: src/sys/dev/i2c/ibmhawkreg.h
diff -u /dev/null src/sys/dev/i2c/ibmhawkreg.h:1.1
--- /dev/null	Mon Feb 14 08:50:40 2011
+++ src/sys/dev/i2c/ibmhawkreg.h	Mon Feb 14 08:50:39 2011
@@ -0,0 +1,86 @@
+/* $NetBSD: ibmhawkreg.h,v 1.1 2011/02/14 08:50:39 hannken Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define IBMHAWK_MAX_CPU		2
+#define IBMHAWK_MAX_VOLTAGE	7
+#define IBMHAWK_MAX_FAN		6
+
+typedef union ibmhawk_response {
+	struct {
+		uint8_t unknown1;
+		uint8_t numcpus;
+		uint8_t unknown2[5];
+		uint8_t numfans;
+	} resp_equip;
+#define IHR_EQUIP		0x51
+#define ihr_numcpus		resp_equip.numcpus
+#define ihr_numfans		resp_equip.numfans
+	struct {
+		uint8_t unknown[4];
+		uint16_t rpm[IBMHAWK_MAX_FAN];
+	} resp_fan;
+#define IHR_FANRPM		0xa2
+#define ihr_fanrpm		resp_fan.rpm
+	struct {
+		char name[16];
+	} resp_name;
+#define IHR_NAME		0x14
+#define ihr_name		resp_name.name
+	struct {
+		uint8_t unknown1[4];
+		uint8_t ambient;
+		uint8_t cpu[IBMHAWK_MAX_CPU];
+		uint8_t unknown2[2];
+	} resp_temp;
+#define IHR_TEMP		0xa4
+#define ihr_t_ambient		resp_temp.ambient
+#define ihr_t_cpu		resp_temp.cpu
+	struct {
+		uint8_t	warn_reset;
+		uint8_t warn;
+		uint8_t soft;
+		uint8_t hard;
+	} resp_temp_thresh;
+#define IHR_TEMP_THR		0xe0
+#define ihr_t_warn_thr		resp_temp_thresh.warn
+#define ihr_t_soft_thr		resp_temp_thresh.soft
+	struct {
+		uint8_t unknown[2];
+		uint16_t voltage[IBMHAWK_MAX_VOLTAGE];
+	} resp_volt;
+#define IHR_VOLT		0xa6
+#define ihr_v_voltage		resp_volt.voltage
+	struct {
+		uint16_t voltage[IBMHAWK_MAX_VOLTAGE*2];
+	} resp_volt_thresh;
+#define IHR_VOLT_THR		0xea
+#define ihr_v_voltage_thr	resp_volt_thresh.voltage
+} ibmhawk_response_t __packed;
Index: src/sys/dev/i2c/ibmhawkvar.h
diff -u /dev/null src/sys/dev/i2c/ibmhawkvar.h:1.1
--- /dev/null	Mon Feb 14 08:50:40 2011
+++ src/sys/dev/i2c/ibmhawkvar.h	Mon Feb 14 08:50:39 2011
@@ -0,0 +1,51 @@
+/* $NetBSD: ibmhawkvar.h,v 1.1 2011/02/14 08:50:39 hannken Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Juergen Hannken-Illjes.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#define IBMHAWK_T_AMBIENT	0
+#define IBMHAWK_T_CPU		1
+#define IBMHAWK_V_VOLTAGE	(IBMHAWK_T_CPU+IBMHAWK_MAX_CPU)
+#define IBMHAWK_F_FAN		(IBMHAWK_V_VOLTAGE+IBMHAWK_MAX_VOLTAGE)
+#define IBMHAWK_MAX_SENSOR	(IBMHAWK_F_FAN+IBMHAWK_MAX_FAN)
+
+struct ibmhawk_softc {
+	device_t sc_dev;
+	i2c_tag_t sc_tag;
+	i2c_addr_t sc_addr;
+	int sc_numcpus;
+	int sc_numfans;
+	int sc_refresh;
+	struct sysmon_envsys *sc_sme;
+	struct ibmhawk_sensordata {
+		envsys_data_t ihs_edata;
+		uint32_t ihs_warnmin;
+		uint32_t ihs_warnmax;
+	} sc_sensordata[IBMHAWK_MAX_SENSOR];
+};

Reply via email to