Subject: Re: port-i386/35796
To: None <port-i386-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <fukumoto@imasy.or.jp>
List: netbsd-bugs
Date: 03/03/2007 13:00:06
The following reply was made to PR port-i386/35796; it has been noted by GNATS.

From: fukumoto@imasy.or.jp
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-i386/35796
Date: Sat, 03 Mar 2007 21:55:26 +0900 (JST)

 Please note that my original report had bogus From: line due to mail
 system misconfiguration.
 
 Attached is an improved patch.  It prevents the crash due to
 zero-division error when the fan tachometer register reads zero.  Also
 added the voltage sensor bias.  For my ASUS M2NPV-VM motherboard, the
 configuration should be like following.  Bias values were obtained
 from acpidump output.
 
 # iTE IT87xxF and compatible hardware monitors
 options IT_SENSORV33="IT_VIN1"
 options IT_VCORE_BIAS=150000		# 150mV
 options IT_V5_BIAS=200000		# 200mV
 options IT_V12_BIAS=400000		# 400mV
 it0	at isa? port 0x290		# other ports: 0xc00, 0xd00
 
 
 Regards,
 
 						FUKUMOTO Atsushi
 						fukumoto@imasy.or.jp
 
 
 Index: sys/dev/isa/files.isa
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/isa/files.isa,v
 retrieving revision 1.144.12.1
 diff -u -u -r1.144.12.1 files.isa
 --- sys/dev/isa/files.isa	12 Jan 2007 23:13:21 -0000	1.144.12.1
 +++ sys/dev/isa/files.isa	3 Mar 2007 12:48:52 -0000
 @@ -468,6 +468,9 @@
  device	it: sysmon_envsys
  attach	it at isa with it_isa
  file	dev/isa/it.c			it_isa
 +defparam opt_it.h	IT_SENSORV33
 +			IT_VCORE_BIAS IT_V33_BIAS IT_V5_BIAS IT_V12_BIAS
 +			IT_VBAT_BIAS
  
  # Abit uGuru hardware monitor
  device ug: sysmon_envsys
 Index: sys/dev/isa/it.c
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/isa/it.c,v
 retrieving revision 1.6.2.1
 diff -u -u -r1.6.2.1 it.c
 --- sys/dev/isa/it.c	9 Jan 2007 14:38:56 -0000	1.6.2.1
 +++ sys/dev/isa/it.c	3 Mar 2007 12:48:53 -0000
 @@ -34,6 +34,8 @@
  #include <sys/cdefs.h>
  __KERNEL_RCSID(0, "$NetBSD: it.c,v 1.6.2.1 2007/01/09 14:38:56 tron Exp $");
  
 +#include "opt_it.h"
 +
  #include <sys/param.h>
  #include <sys/systm.h>
  #include <sys/kernel.h>
 @@ -71,6 +73,22 @@
  #define RFACT_NONE	10000
  #define RFACT(x, y)	(RFACT_NONE * ((x) + (y)) / (y))
  
 +#ifndef IT_VCORE_BIAS
 +# define IT_VCORE_BIAS	0
 +#endif
 +#ifndef IT_V33_BIAS
 +# define IT_V33_BIAS	0
 +#endif
 +#ifndef IT_V5_BIAS
 +# define IT_V5_BIAS	0
 +#endif
 +#ifndef IT_V12_BIAS
 +# define IT_V12_BIAS	0
 +#endif
 +#ifndef IT_VBAT_BIAS
 +# define IT_VBAT_BIAS	0
 +#endif
 +
  /* autoconf(9) functions */
  static int  it_isa_match(struct device *, struct cfdata *, void *);
  static void it_isa_attach(struct device *, struct device *, void *);
 @@ -109,6 +127,15 @@
  	RFACT_NONE	/* VBAT  */
  };
  
 +/* bias for voltage sensors */
 +static const int it_vbias[] = {
 +	IT_VCORE_BIAS,
 +	IT_V33_BIAS,
 +	IT_V5_BIAS,
 +	IT_V12_BIAS,
 +	IT_VBAT_BIAS
 +};
 +
  static int
  it_isa_match(struct device *parent, struct cfdata *match, void *aux)
  {
 @@ -155,6 +182,7 @@
  	}
  
  	idr = it_readreg(sc, IT_COREID);
 +	sc->id = idr;
  	if (idr == IT_REV_8712)
  		aprint_normal(": IT8712F Hardware monitor\n");
  	else {
 @@ -305,6 +333,7 @@
  		sc->sc_data[2 + i].cur.data_s *= it_vrfact[i];
  		/* division by 10 gets us back to uVDC */
  		sc->sc_data[2 + i].cur.data_s /= 10;
 +		sc->sc_data[2 + i].cur.data_s += it_vbias[i];
  		sc->sc_info[2 + i].rfact = sc->sc_data[2 + i].cur.data_s;
  	}
  }
 @@ -312,27 +341,52 @@
  static void
  it_refresh_fans(struct it_softc *sc)
  {
 +	int mode;
  	int i, sdata, divisor, odivisor, ndivisor;
  
 -	odivisor = ndivisor = divisor = it_readreg(sc, IT_FAN);
 -	for (i = 0; i < 2; i++, divisor >>= 3) {
 -		if ((sdata = it_readreg(sc, IT_SENSORFANBASE + i)) == 0xff) {
 -			if (i == 2)
 -				ndivisor ^= 0x40;
 -			else {
 -				ndivisor &= ~(7 << (i * 3));
 -				ndivisor |= ((divisor + 1) & 7) << (i * 3);
 +	mode = it_readreg(sc, IT_FAN16);
 +	if (sc->id == IT_REV_8705) {
 +		odivisor = ndivisor = divisor = it_readreg(sc, IT_FAN);
 +		for (i = 0; i < 2; i++, divisor >>= 3) {
 +			sdata = it_readreg(sc, IT_SENSORFANBASE + i);
 +			if (mode & (1 << i))
 +				sdata += (it_readreg(sc, IT_SENSORFANEXTBASE + i) << 8);
 +			if (!(mode & (1 << i)) && sdata == 0xff) {
 +				if (i == 2)
 +					ndivisor |= 0x40;
 +				else if ((divisor & 7) != 7) {
 +					ndivisor &= ~(7 << (i * 3));
 +					ndivisor |= ((divisor + 1) & 7) << (i * 3);
 +				}
 +			} else {
 +				if (i == 2)
 +					divisor = divisor & 1 ? 3 : 1;
 +				if ((sdata << (divisor & 7)) == 0)
 +					sc->sc_data[7 + i].cur.data_us = 0;
 +				else
 +					sc->sc_data[7 + i].cur.data_us =
 +					    1350000 / (sdata << (divisor & 7));
 +			}
 +			DPRINTF(("sdata[fan%d] 0x%x div: 0x%x\n", i, sdata, divisor));
 +		}
 +		if (ndivisor != odivisor)
 +			it_writereg(sc, IT_FAN, ndivisor);
 +	} else {
 +		/* IT8712F, IT8716F */
 +		for (i = 0; i < 2; i++) {
 +			sdata = it_readreg(sc, IT_SENSORFANBASE + i);
 +			if (mode & (1 << i)) /* 16-bit mode enabled */
 +				sdata += (it_readreg(sc, IT_SENSORFANEXTBASE + i) << 8);
 +			if (sdata == 0 ||
 +			    sdata == ((mode & (1 << i)) ? 0xFFFF : 0xFF)) {
 +				sc->sc_data[7 + i].cur.data_us = 0;
 +			} else {
 +				sc->sc_data[7 + i].cur.data_us =
 +				    1350000 / 2 / sdata;
  			}
 -		} else {
 -			if (i == 2)
 -				divisor = divisor & 1 ? 3 : 1;
 -			sc->sc_data[7 + i].cur.data_us =
 -			    1350000 / (sdata << (divisor & 7));
 +			DPRINTF(("sdata[fan%d] 0x%x\n", i, sdata));
  		}
 -		DPRINTF(("sdata[fan%d] 0x%x div: 0x%x\n", i, sdata, divisor));
  	}
 -	if (ndivisor != odivisor)
 -		it_writereg(sc, IT_FAN, ndivisor);
  }
  
  static int              
 Index: sys/dev/isa/itvar.h
 ===================================================================
 RCS file: /cvsroot/src/sys/dev/isa/itvar.h,v
 retrieving revision 1.2.14.1
 diff -u -u -r1.2.14.1 itvar.h
 --- sys/dev/isa/itvar.h	9 Jan 2007 14:38:56 -0000	1.2.14.1
 +++ sys/dev/isa/itvar.h	3 Mar 2007 12:48:53 -0000
 @@ -55,6 +55,7 @@
  #define IT_IMR3 	0x09
  #define IT_VID 		0x0a
  #define IT_FAN 		0x0b
 +#define	IT_FAN16	0x0c
  
  #define IT_VOLTENABLE 	0x50
  #define IT_TEMPENABLE 	0x51
 @@ -63,13 +64,25 @@
  #define IT_FANENABLE	0x13
  
  #define IT_SENSORFANBASE	0x0d	/* Fan from 0x0d to 0x0f */
 -#define IT_SENSORVOLTBASE	0x20	/* Fan from 0x20 to 0x28 */
 -#define IT_SENSORTEMPBASE	0x29	/* Fan from 0x29 to 0x2b */
 -
 -#define IT_SENSORVCORE0		0x20
 -#define IT_SENSORV33		0x22
 -#define IT_SENSORV5		0x23
 -#define IT_SENSORV12		0x24
 +#define	IT_SENSORFANEXTBASE	0x18	/* Fan (MSB) from 0x18 to 0x1A */
 +#define IT_SENSORVOLTBASE	0x20	/* Voltage from 0x20 to 0x28 */
 +#define IT_SENSORTEMPBASE	0x29	/* Temperature from 0x29 to 0x2b */
 +
 +#define	IT_VIN0			0x20
 +#define	IT_VIN1			0x21
 +#define	IT_VIN2			0x22
 +#define	IT_VIN3			0x23
 +#define	IT_VIN4			0x24
 +#define	IT_VIN5			0x25
 +#define	IT_VIN6			0x26
 +#define	IT_VIN7			0x27
 +
 +#define IT_SENSORVCORE0		IT_VIN0
 +#ifndef IT_SENSORV33
 +# define IT_SENSORV33		IT_VIN2
 +#endif
 +#define IT_SENSORV5		IT_VIN3
 +#define IT_SENSORV12		IT_VIN4
  #define IT_SENSORVBAT		0x28
  
  #define IT_VOLTMAXBASE		0x30
 @@ -105,6 +118,8 @@
  	struct sysmon_envsys sc_sysmon;
  	envsys_tre_data_t sc_data[IT_NUM_SENSORS];
  	envsys_basic_info_t sc_info[IT_NUM_SENSORS];
 +
 +	uint8_t	id;
  };
  
  #endif /* _DEV_ISA_ITVAR_H_ */