Patchwork [3.5.y.z,extended,stable] Patch "hwmon: (lm73} Detect and report i2c bus errors" has been added to staging queue

login
register
mail settings
Submitter Herton Ronaldo Krzesinski
Date Jan. 10, 2013, 9:02 p.m.
Message ID <1357851764-23615-1-git-send-email-herton.krzesinski@canonical.com>
Download mbox | patch
Permalink /patch/211150/
State New
Headers show

Comments

Herton Ronaldo Krzesinski - Jan. 10, 2013, 9:02 p.m.
This is a note to let you know that I have just added a patch titled

    hwmon: (lm73} Detect and report i2c bus errors

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Herton

------

From 1061369743a75da44af0c90a3bff67b770a52b52 Mon Sep 17 00:00:00 2001
From: Chris Verges <kg4ysn@gmail.com>
Date: Fri, 21 Dec 2012 01:58:34 -0800
Subject: [PATCH] hwmon: (lm73} Detect and report i2c bus errors

commit 0602934f302e016e2ea5dc6951681bfac77455ef upstream.

If an LM73 device does not exist on an I2C bus, attempts to communicate
with the device result in an error code returned from the i2c read/write
functions.  The current lm73 driver casts that return value from a s32
type to a s16 type, then converts it to a temperature in celsius.
Because negative temperatures are valid, it is difficult to distinguish
between an error code printed to the response buffer and a negative
temperature recorded by the sensor.

The solution is to evaluate the return value from the i2c functions
before performing any temperature calculations.  If the i2c function did
not succeed, the error code should be passed back through the virtual
file system layer instead of being printed into the response buffer.

Before:

   $ cat /sys/class/hwmon/hwmon0/device/temp1_input
   -46

After:

   $ cat /sys/class/hwmon/hwmon0/device/temp1_input
   cat: read error: No such device or address

Signed-off-by: Chris Verges <kg4ysn@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Herton Ronaldo Krzesinski <herton.krzesinski@canonical.com>
---
 drivers/hwmon/lm73.c |   16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

--
1.7.9.5

Patch

diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c
index 8fa2632..7272176 100644
--- a/drivers/hwmon/lm73.c
+++ b/drivers/hwmon/lm73.c
@@ -49,6 +49,7 @@  static ssize_t set_temp(struct device *dev, struct device_attribute *da,
 	struct i2c_client *client = to_i2c_client(dev);
 	long temp;
 	short value;
+	s32 err;

 	int status = kstrtol(buf, 10, &temp);
 	if (status < 0)
@@ -57,8 +58,8 @@  static ssize_t set_temp(struct device *dev, struct device_attribute *da,
 	/* Write value */
 	value = (short) SENSORS_LIMIT(temp/250, (LM73_TEMP_MIN*4),
 		(LM73_TEMP_MAX*4)) << 5;
-	i2c_smbus_write_word_swapped(client, attr->index, value);
-	return count;
+	err = i2c_smbus_write_word_swapped(client, attr->index, value);
+	return (err < 0) ? err : count;
 }

 static ssize_t show_temp(struct device *dev, struct device_attribute *da,
@@ -66,11 +67,16 @@  static ssize_t show_temp(struct device *dev, struct device_attribute *da,
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct i2c_client *client = to_i2c_client(dev);
+	int temp;
+
+	s32 err = i2c_smbus_read_word_swapped(client, attr->index);
+	if (err < 0)
+		return err;
+
 	/* use integer division instead of equivalent right shift to
 	   guarantee arithmetic shift and preserve the sign */
-	int temp = ((s16) (i2c_smbus_read_word_swapped(client,
-		    attr->index))*250) / 32;
-	return sprintf(buf, "%d\n", temp);
+	temp = (((s16) err) * 250) / 32;
+	return scnprintf(buf, PAGE_SIZE, "%d\n", temp);
 }