From patchwork Mon Dec 5 04:55:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guenter Roeck X-Patchwork-Id: 9460339 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 49F4D6022E for ; Mon, 5 Dec 2016 06:04:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4038F24B5B for ; Mon, 5 Dec 2016 06:04:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 351E22621D; Mon, 5 Dec 2016 06:04:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9B91324B5B for ; Mon, 5 Dec 2016 06:04:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751411AbcLEGEp (ORCPT ); Mon, 5 Dec 2016 01:04:45 -0500 Received: from bh-25.webhostbox.net ([208.91.199.152]:51807 "EHLO bh-25.webhostbox.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751039AbcLEGEo (ORCPT ); Mon, 5 Dec 2016 01:04:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=roeck-us.net; s=default; h=References:In-Reply-To:Message-Id:Date:Subject: Cc:To:From; bh=Q4dHxNvulfANxybU5pYlPzosXRhatyN9ymc7r5JDZtc=; b=Ws9tVqCex/yKD6 DJpBX64f4nvnf3y3BjYpK8iDqvnEqRJ0Vpq08ALC23Fw14P18XGPjunP1PZS1Tl1+iGRYm46MSlbo rDfTsChs0aJujhTiDjP2ZICIIHb6M+bmnfeck1+J2gJ6Ra+3irXkdPxwoIYVXMZDKQhVZ7sD8L38F NgdRNmgBbxuEsbs/slliqb8hi9ujzRwNmP9T0EH/N+miQDZnKcfOtjvD6hTyu5rug0CyPfAQbe1EA 4SvLbwsNcphzdJNf72lHgulMa8Vc/aZtv9b8AdbVIdT1WctU0iytzsAuoqZb67PwxwOi0fwsvbReA vOwBFkNgAvKcblgEVTUA==; Received: from 108-223-40-66.lightspeed.sntcca.sbcglobal.net ([108.223.40.66]:49756 helo=localhost) by bh-25.webhostbox.net with esmtpa (Exim 4.86_1) (envelope-from ) id 1cDlJY-0008w4-Ud; Mon, 05 Dec 2016 04:55:45 +0000 From: Guenter Roeck To: Hardware Monitoring Cc: Jean Delvare , Guenter Roeck Subject: [PATCH 03/17] hwmon: (lm93) Fix overflows seen when writing into limit attributes Date: Sun, 4 Dec 2016 20:55:26 -0800 Message-Id: <1480913740-5678-3-git-send-email-linux@roeck-us.net> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1480913740-5678-1-git-send-email-linux@roeck-us.net> References: <1480913740-5678-1-git-send-email-linux@roeck-us.net> X-Authenticated_sender: guenter@roeck-us.net X-OutGoing-Spam-Status: No, score=-1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - bh-25.webhostbox.net X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - roeck-us.net X-Get-Message-Sender-Via: bh-25.webhostbox.net: authenticated_id: guenter@roeck-us.net X-Authenticated-Sender: bh-25.webhostbox.net: guenter@roeck-us.net X-Source: X-Source-Args: X-Source-Dir: Sender: linux-hwmon-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-hwmon@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Module test shows a large number of overflows, caused by missing clamps as well as various conversions between variable types. Also fix temperature calculations for hysteresis and offset registers. For those, temperature calculations were a mix of millisecond and second based, causing reported and accepted hysteresis and offset temperatures to be widely off target. This also changes the offset and base temperature attributes to be officially reported and set in milli-degrees C. This was already the case for the base temperature attribute, even though it was documented to be reported and set in degrees C. Signed-off-by: Guenter Roeck Reviewed-by: Jean Delvare --- Documentation/hwmon/lm93 | 26 ++++++++++++------------- drivers/hwmon/lm93.c | 49 +++++++++++++++++++++++++----------------------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/Documentation/hwmon/lm93 b/Documentation/hwmon/lm93 index f3b2ad2ceb01..7bda7f0291e4 100644 --- a/Documentation/hwmon/lm93 +++ b/Documentation/hwmon/lm93 @@ -174,25 +174,25 @@ a "0" disables it. The h/w default is 0x0f (all temperatures bound). The function y = f(x) takes a source temperature x to a PWM output y. This function of the LM93 is derived from a base temperature and a table of 12 -temperature offsets. The base temperature is expressed in degrees C in the -sysfs files temp_auto_base. The offsets are expressed in cumulative -degrees C, with the value of offset for temperature value being +temperature offsets. The base temperature is expressed in milli-degrees C in +the sysfs files temp_auto_base. The offsets are expressed in cumulative +milli-degrees C, with the value of offset for temperature value being contained in the file temp_auto_offset. E.g. if the base temperature is 40C: offset # temp_auto_offset range pwm 1 0 - 25.00% 2 0 - 28.57% - 3 1 40C - 41C 32.14% - 4 1 41C - 42C 35.71% - 5 2 42C - 44C 39.29% - 6 2 44C - 46C 42.86% - 7 2 48C - 50C 46.43% - 8 2 50C - 52C 50.00% - 9 2 52C - 54C 53.57% - 10 2 54C - 56C 57.14% - 11 2 56C - 58C 71.43% - 12 2 58C - 60C 85.71% + 3 500 40C - 41C 32.14% + 4 500 41C - 42C 35.71% + 5 1000 42C - 44C 39.29% + 6 1000 44C - 46C 42.86% + 7 1000 48C - 50C 46.43% + 8 1000 50C - 52C 50.00% + 9 1000 52C - 54C 53.57% + 10 1000 54C - 56C 57.14% + 11 1000 56C - 58C 71.43% + 12 1000 58C - 60C 85.71% > 60C 100.00% Valid offsets are in the range 0C <= x <= 7.5C in 0.5C increments. diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c index 90bb04858117..7b3152368e3b 100644 --- a/drivers/hwmon/lm93.c +++ b/drivers/hwmon/lm93.c @@ -368,7 +368,7 @@ static unsigned LM93_IN_FROM_REG(int nr, u8 reg) * IN: mV, limits determined by channel nr * REG: scaling determined by channel nr */ -static u8 LM93_IN_TO_REG(int nr, unsigned val) +static u8 LM93_IN_TO_REG(int nr, unsigned long val) { /* range limit */ const long mv = clamp_val(val, @@ -407,9 +407,13 @@ static unsigned LM93_IN_REL_FROM_REG(u8 reg, int upper, int vid) * upper also determines which nibble of the register is returned * (the other nibble will be 0x0) */ -static u8 LM93_IN_REL_TO_REG(unsigned val, int upper, int vid) +static u8 LM93_IN_REL_TO_REG(unsigned long val, int upper, int vid) { - long uv_offset = vid * 1000 - val * 10000; + long uv_offset; + + val = clamp_val(val, 0, 1000000); + uv_offset = vid * 1000 - val * 10000; + if (upper) { uv_offset = clamp_val(uv_offset, 12500, 200000); return (u8)((uv_offset / 12500 - 1) << 4); @@ -453,28 +457,23 @@ static int LM93_TEMP_OFFSET_MODE_FROM_REG(u8 sfc2, int nr) * This function is common to all 4-bit temperature offsets * reg is 4 bits right justified * mode 0 => 1C/bit, mode !0 => 0.5C/bit + * Return value in milli-degrees C. */ static int LM93_TEMP_OFFSET_FROM_REG(u8 reg, int mode) { - return (reg & 0x0f) * (mode ? 5 : 10); + return (reg & 0x0f) * (mode ? 500 : 1000); } -#define LM93_TEMP_OFFSET_MIN (0) -#define LM93_TEMP_OFFSET_MAX0 (150) -#define LM93_TEMP_OFFSET_MAX1 (75) - /* * This function is common to all 4-bit temperature offsets * returns 4 bits right justified * mode 0 => 1C/bit, mode !0 => 0.5C/bit + * Input value is in milli-degrees C. */ -static u8 LM93_TEMP_OFFSET_TO_REG(int off, int mode) +static u8 LM93_TEMP_OFFSET_TO_REG(unsigned long off, int mode) { - int factor = mode ? 5 : 10; - - off = clamp_val(off, LM93_TEMP_OFFSET_MIN, - mode ? LM93_TEMP_OFFSET_MAX1 : LM93_TEMP_OFFSET_MAX0); - return (u8)((off + factor/2) / factor); + off = clamp_val(off, 0, mode ? 7500 : 15000); + return DIV_ROUND_CLOSEST(off, mode ? 500 : 1000); } /* 0 <= nr <= 3 */ @@ -494,7 +493,8 @@ static int LM93_TEMP_AUTO_OFFSET_FROM_REG(u8 reg, int nr, int mode) * REG: 1.0C/bit (mode 0) or 0.5C/bit (mode non-zero) * 0 <= nr <= 3 */ -static u8 LM93_TEMP_AUTO_OFFSET_TO_REG(u8 old, int off, int nr, int mode) +static u8 LM93_TEMP_AUTO_OFFSET_TO_REG(u8 old, unsigned long off, int nr, + int mode) { u8 new = LM93_TEMP_OFFSET_TO_REG(off, mode); @@ -532,10 +532,13 @@ static int LM93_AUTO_BOOST_HYST_FROM_REGS(struct lm93_data *data, int nr, LM93_TEMP_OFFSET_FROM_REG(reg, mode); } -static u8 LM93_AUTO_BOOST_HYST_TO_REG(struct lm93_data *data, long hyst, - int nr, int mode) +static u8 LM93_AUTO_BOOST_HYST_TO_REG(struct lm93_data *data, + long hyst, int nr, int mode) { - u8 reg = LM93_TEMP_OFFSET_TO_REG( + u8 reg; + + hyst = clamp_val(hyst, LM93_TEMP_MIN, LM93_TEMP_MAX); + reg = LM93_TEMP_OFFSET_TO_REG( (LM93_TEMP_FROM_REG(data->boost[nr]) - hyst), mode); switch (nr) { @@ -592,7 +595,7 @@ static int LM93_PWM_FROM_REG(u8 reg, enum pwm_freq freq) } /* round up to nearest match */ -static u8 LM93_PWM_TO_REG(int pwm, enum pwm_freq freq) +static u8 LM93_PWM_TO_REG(unsigned long pwm, enum pwm_freq freq) { int i; for (i = 0; i < 13; i++) @@ -613,7 +616,7 @@ static int LM93_FAN_FROM_REG(u16 regs) * RPM: (82.5 to 1350000) * REG: 14-bits, LE, *left* justified */ -static u16 LM93_FAN_TO_REG(long rpm) +static u16 LM93_FAN_TO_REG(unsigned long rpm) { u16 count, regs; @@ -642,7 +645,7 @@ static int LM93_PWM_FREQ_FROM_REG(u8 reg) } /* round up to nearest match */ -static u8 LM93_PWM_FREQ_TO_REG(int freq) +static u8 LM93_PWM_FREQ_TO_REG(unsigned long freq) { int i; for (i = 7; i > 0; i--) @@ -1471,10 +1474,10 @@ static ssize_t store_temp_auto_boost_hyst(struct device *dev, int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; - unsigned long val; + long val; int err; - err = kstrtoul(buf, 10, &val); + err = kstrtol(buf, 10, &val); if (err) return err;