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];
+};