From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: Justin Forbes <jmforbes@linuxtx.org>,
Zwane Mwaikambo <zwane@arm.linux.org.uk>,
"Theodore Ts'o" <tytso@mit.edu>,
Randy Dunlap <rdunlap@xenotime.net>,
Dave Jones <davej@redhat.com>,
Chuck Wolber <chuckw@quantumlinux.com>,
Chris Wedgwood <reviews@ml.cw.f00f.org>,
Michael Krufky <mkrufky@linuxtv.org>,
Chuck Ebbert <cebbert@redhat.com>,
Domenico Andreoli <cavokz@gmail.com>,
torvalds@linux-foundation.org, akpm@linux-foundation.org,
alan@lxorguk.ukuu.org.uk, David Brownell <david-b@pacbell.net>,
David Brownell <dbrownell@users.sourceforge.net>,
Jean Delvare <khali@linux-fr.org>
Subject: [patch 07/12] i2c-algo-bit: Read block data bugfix
Date: Mon, 8 Oct 2007 11:06:25 -0700 [thread overview]
Message-ID: <20071008180625.GH7627@kroah.com> (raw)
In-Reply-To: <20071008180551.GA7627@kroah.com>
[-- Attachment #1: i2c-algo-bit-read-block-data-bugfix.patch --]
[-- Type: text/plain, Size: 3455 bytes --]
From: David Brownell <david-b@pacbell.net>
In Linus tree already:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=939bc4943d0483961edc45b63a7d27b4ffe547e3
This fixes a bug in the way i2c-algo-bit handles I2C_M_RECV_LEN,
used to implement i2c_smbus_read_block_data(). Previously, in the
absence of PEC (rarely used!) it would NAK the "length" byte:
S addr Rd [A] [length] NA
That prevents the subsequent data bytes from being read:
S addr Rd [A] [length] { A [data] }* NA
The primary fix just reorders two code blocks, so the length used
in the "should I NAK now?" check incorporates the data which it
just read from the slave device.
However, that move also highlighted other fault handling glitches.
This fixes those by abstracting the RX path ack/nak logic, so it
can be used in more than one location.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
drivers/i2c/algos/i2c-algo-bit.c | 52 ++++++++++++++++++++++++---------------
1 file changed, 32 insertions(+), 20 deletions(-)
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -357,13 +357,29 @@ static int sendbytes(struct i2c_adapter
return wrcount;
}
+static int acknak(struct i2c_adapter *i2c_adap, int is_ack)
+{
+ struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
+
+ /* assert: sda is high */
+ if (is_ack) /* send ack */
+ setsda(adap, 0);
+ udelay((adap->udelay + 1) / 2);
+ if (sclhi(adap) < 0) { /* timeout */
+ dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n");
+ return -ETIMEDOUT;
+ }
+ scllo(adap);
+ return 0;
+}
+
static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
{
int inval;
int rdcount=0; /* counts bytes read */
- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
unsigned char *temp = msg->buf;
int count = msg->len;
+ const unsigned flags = msg->flags;
while (count > 0) {
inval = i2c_inb(i2c_adap);
@@ -377,28 +393,12 @@ static int readbytes(struct i2c_adapter
temp++;
count--;
- if (msg->flags & I2C_M_NO_RD_ACK) {
- bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x\n",
- inval);
- continue;
- }
-
- /* assert: sda is high */
- if (count) /* send ack */
- setsda(adap, 0);
- udelay((adap->udelay + 1) / 2);
- bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x %s\n", inval,
- count ? "A" : "NA");
- if (sclhi(adap)<0) { /* timeout */
- dev_err(&i2c_adap->dev, "readbytes: timeout at ack\n");
- return -ETIMEDOUT;
- };
- scllo(adap);
-
/* Some SMBus transactions require that we receive the
transaction length as the first read byte. */
- if (rdcount == 1 && (msg->flags & I2C_M_RECV_LEN)) {
+ if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) {
if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
+ if (!(flags & I2C_M_NO_RD_ACK))
+ acknak(i2c_adap, 0);
dev_err(&i2c_adap->dev, "readbytes: invalid "
"block length (%d)\n", inval);
return -EREMOTEIO;
@@ -409,6 +409,18 @@ static int readbytes(struct i2c_adapter
count += inval;
msg->len += inval;
}
+
+ bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n",
+ inval,
+ (flags & I2C_M_NO_RD_ACK)
+ ? "(no ack/nak)"
+ : (count ? "A" : "NA"));
+
+ if (!(flags & I2C_M_NO_RD_ACK)) {
+ inval = acknak(i2c_adap, count);
+ if (inval < 0)
+ return inval;
+ }
}
return rdcount;
}
--
next prev parent reply other threads:[~2007-10-08 18:25 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20071008180406.052382073@mini.kroah.org>
2007-10-08 18:05 ` [patch 00/12] 2.6.22.10 -stable review Greg KH
2007-10-08 18:06 ` [patch 01/12] scsi_transport_spi: fix domain validation failure from incorrect width setting Greg KH
2007-10-08 18:06 ` [patch 02/12] sky2: reduce impact of watchdog timer Greg KH
2007-10-08 18:06 ` [patch 03/12] sky2: fix VLAN receive processing Greg KH
2007-10-08 18:06 ` [patch 04/12] sky2: fix transmit state on resume Greg KH
2007-10-08 18:06 ` [patch 05/12] libata: update drive blacklists Greg KH
2007-10-08 18:06 ` [patch 06/12] Fix ppp_mppe kernel stack usage Greg KH
2007-10-08 18:06 ` Greg KH [this message]
2007-10-08 18:06 ` [patch 08/12] NLM: Fix a circular lock dependency in lockd Greg KH
2007-10-08 20:01 ` Roel Kluin
2007-10-09 15:00 ` Trond Myklebust
2007-10-09 15:13 ` Greg KH
2007-10-09 15:27 ` Trond Myklebust
2007-10-09 20:41 ` [stable] " Greg KH
2007-10-08 18:06 ` [patch 09/12] Fix SMP poweroff hangs Greg KH
2007-10-09 15:17 ` Olof Johansson
2007-10-09 22:20 ` [stable] " Greg KH
2007-10-09 23:21 ` Thomas Gleixner
2007-10-09 23:27 ` Linus Torvalds
2007-10-09 23:35 ` Thomas Gleixner
2007-10-10 5:29 ` Linus Torvalds
[not found] ` <200710092359.47144.spaceman__spiff@cox.net>
2007-10-10 14:57 ` ARPM shutdown oops (Re: [stable] [patch 09/12] Fix SMP poweroff hangs) Linus Torvalds
2007-10-10 16:31 ` H. Peter Anvin
2007-10-11 3:05 ` Kevin
2007-10-11 15:31 ` Linus Torvalds
2007-10-11 18:42 ` Jeff Garzik
2007-10-11 19:19 ` Dave Jones
2007-10-11 20:55 ` Rafael J. Wysocki
2007-10-11 23:27 ` APM " Adrian Bunk
2007-10-12 12:05 ` Rafael J. Wysocki
2007-10-10 0:03 ` [stable] [patch 09/12] Fix SMP poweroff hangs Olof Johansson
2007-10-10 0:08 ` [PATCH] powerpc: don't enable cpu hotplug on mpic-based pseries Olof Johansson
2007-10-10 0:18 ` Stephen Rothwell
2007-10-10 0:38 ` [PATCH v2] " Olof Johansson
2007-10-10 10:08 ` Milton Miller
2007-10-10 16:43 ` Olof Johansson
2007-10-11 5:52 ` Paul Mackerras
2007-10-11 5:59 ` Olof Johansson
2007-10-11 0:24 ` [stable] [patch 09/12] Fix SMP poweroff hangs Paul Mackerras
2007-10-09 23:28 ` Greg KH
[not found] ` <alpine.LFD.0.999.0710091625520.3838@woody.linux%foundation.org>
2007-10-10 10:06 ` Milton Miller
2007-10-10 11:35 ` Rafael J. Wysocki
2007-10-08 18:06 ` [patch 10/12] Fix timer_stats printout of events/sec Greg KH
2007-10-08 18:06 ` [patch 11/12] SELinux: clear parent death signal on SID transitions Greg KH
2007-10-08 18:06 ` [patch 12/12] i386: Use global flag to disable broken local apic timer on AMD CPUs Greg KH
2007-10-08 18:09 ` [patch 00/12] 2.6.22.10 -stable review Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071008180625.GH7627@kroah.com \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=cavokz@gmail.com \
--cc=cebbert@redhat.com \
--cc=chuckw@quantumlinux.com \
--cc=davej@redhat.com \
--cc=david-b@pacbell.net \
--cc=dbrownell@users.sourceforge.net \
--cc=jmforbes@linuxtx.org \
--cc=khali@linux-fr.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mkrufky@linuxtv.org \
--cc=rdunlap@xenotime.net \
--cc=reviews@ml.cw.f00f.org \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=tytso@mit.edu \
--cc=zwane@arm.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox