healthd may return some unexpected negative values when using SMB method to get hardware readings. this happens because of confusing type usage in getMB-smb.c, function ReadByte(): static int ReadByte(int addr) { unsigned char count = 0; struct smbcmd cmd; char ret; .. return (unsigned int)ret; } if char type is signed (which is the case for i386) and if ret variable contains a negative value (corresponding to 0x80-0xFF range) then this function will return the same negative value, only as int, despite an obvious, but obviously incorrect attempt to cast return value to unsigned type. Value returned from this function in some cases is assigned to unsigned char variable which makes things sane, but in other cases it is used directly in calculations, so this problem can not observed for all parameters. the most likely candidate is 3.3 volatge. Fix: change return statement in ReadByte for correct casting to unsigned byte: - return (unsigned int)ret; + return (unsigned char)ret; better yet, change interface to appropriate one that would return unsigned char instead of too wide int. How-To-Repeat: 1. compile healthd with SMB support and run it on a SMB HWM-enabled system, to ensure that SMB is used run healthd with -S option, also use -d option to get debug output 2. check +3.3V voltage value, you will negative value (about -0.70) instead of a correct value
Responsible Changed From-To: freebsd-bugs->freebsd-bugs
Responsible Changed From-To: freebsd-bugs->jeh Recover this PR from the mess I made with the last edit, and reassign PR to healthd maintainer.
I am sorry for my hastiness - this PR shoould go to "ports" category, not "misc". Also, error condition was tested for non-LM80 monitor type (namely winbond W83783S) -- Andriy Gapon
State Changed From-To: open->analyzed This is being looked at
State Changed From-To: analyzed->closed Committed