Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754202Ab0LMA2j (ORCPT ); Sun, 12 Dec 2010 19:28:39 -0500 Received: from one.firstfloor.org ([213.235.205.2]:44735 "EHLO one.firstfloor.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754063Ab0LLXp2 (ORCPT ); Sun, 12 Dec 2010 18:45:28 -0500 From: Andi Kleen References: <201012131244.547034648@firstfloor.org> In-Reply-To: <201012131244.547034648@firstfloor.org> To: FlorianSchandinat@gmx.de, corbet@lwn.net, JosephChan@via.com.tw, gregkh@suse.de, ak@linux.intel.com, linux-kernel@vger.kernel.org, stable@kernel.org Subject: [PATCH] [31/223] viafb: fix i2c_transfer error handling Message-Id: <20101212234527.80A54B27BF@basil.firstfloor.org> Date: Mon, 13 Dec 2010 00:45:27 +0100 (CET) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3219 Lines: 101 2.6.35-longterm review patch. If anyone has any objections, please let me know. ------------------ From: Florian Tobias Schandinat commit 85c5702ac046b14713f776d59768252d8ed8018f upstream. i2c_transfer returns negative errno on error and number of messages processed on success. Just returning this value would give a poor interface as it is not obvious that you must compare with 2 after reading 1 or n bytes and with 1 after writing 1 byte to determine if it was successful. To avoid this error prone interface convert the error code of a successful read/write to zero and all other non-negative values to an negative error code. This fixes a regression introduced by via: Rationalize vt1636 detection which resulted in no longer detecting a VT1636 chip and therefore has broken the output in configurations which contain this chip. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan Signed-off-by: Greg Kroah-Hartman Signed-off-by: Andi Kleen --- drivers/video/via/via_i2c.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) Index: linux/drivers/video/via/via_i2c.c =================================================================== --- linux.orig/drivers/video/via/via_i2c.c +++ linux/drivers/video/via/via_i2c.c @@ -114,6 +114,7 @@ static void via_i2c_setsda(void *data, i int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) { + int ret; u8 mm1[] = {0x00}; struct i2c_msg msgs[2]; @@ -126,11 +127,18 @@ int viafb_i2c_readbyte(u8 adap, u8 slave mm1[0] = index; msgs[0].len = 1; msgs[1].len = 1; msgs[0].buf = mm1; msgs[1].buf = pdata; - return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + if (ret == 2) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; } int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) { + int ret; u8 msg[2] = { index, data }; struct i2c_msg msgs; @@ -140,11 +148,18 @@ int viafb_i2c_writebyte(u8 adap, u8 slav msgs.addr = slave_addr / 2; msgs.len = 2; msgs.buf = msg; - return i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1); + ret = i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1); + if (ret == 1) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; } int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) { + int ret; u8 mm1[] = {0x00}; struct i2c_msg msgs[2]; @@ -156,7 +171,13 @@ int viafb_i2c_readbytes(u8 adap, u8 slav mm1[0] = index; msgs[0].len = 1; msgs[1].len = buff_len; msgs[0].buf = mm1; msgs[1].buf = buff; - return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + if (ret == 2) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; } /* -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/