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