public inbox for linux-i2c@vger.kernel.org
 help / color / mirror / Atom feed
From: Tam Nguyen <tamnguyenchi@os.amperecomputing.com>
To: linux-kernel@vger.kernel.org, linux-i2c@vger.kernel.org
Cc: patches@amperecomputing.com, jarkko.nikula@linux.intel.com,
	andriy.shevchenko@linux.intel.com,
	mika.westerberg@linux.intel.com, jsd@semihalf.com,
	tamnguyenchi@os.amperecomputing.com,
	chuong@os.amperecomputing.com, darren@os.amperecomputing.com,
	stable@vger.kernel.org
Subject: [PATCH v1] i2c: designware: Handle invalid SMBus block data response length
Date: Tue, 23 May 2023 15:21:18 +0700	[thread overview]
Message-ID: <20230523082118.10935-1-tamnguyenchi@os.amperecomputing.com> (raw)

In I2C_FUNC_SMBUS_BLOCK_DATA case, the I2C Designware driver does not
handle correctly when it receives the length of SMBus block data
response from SMBus slave device, which is outside the range 1-32 bytes.
Consequently, the I2C Designware bus is stuck and cannot recover.
Because if IC_EMPTYFIFO_HOLD_MASTER_EN is set, which cannot be detected
from the registers, the controller can be disabled if the STOP bit is set.
But it is only set after receiving block data response length.

Hence, to prevent the bus from stuck condition, after receiving the
invalid block data response length, the driver will read another byte
with STOP bit set.

Cc: stable@vger.kernel.org
Signed-off-by: Tam Nguyen <tamnguyenchi@os.amperecomputing.com>
---
 drivers/i2c/busses/i2c-designware-master.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c
index 55ea91a63382..94dadd785ed0 100644
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -527,8 +527,19 @@ i2c_dw_read(struct dw_i2c_dev *dev)
 
 			regmap_read(dev->map, DW_IC_DATA_CMD, &tmp);
 			/* Ensure length byte is a valid value */
-			if (flags & I2C_M_RECV_LEN &&
-			    (tmp & DW_IC_DATA_CMD_DAT) <= I2C_SMBUS_BLOCK_MAX && tmp > 0) {
+			if (flags & I2C_M_RECV_LEN) {
+				/*
+				 * if IC_EMPTYFIFO_HOLD_MASTER_EN is set, which cannot be
+				 * detected from the registers, the controller can be
+				 * disabled if the STOP bit is set. But it is only set
+				 * after receiving block data response length in
+				 * I2C_FUNC_SMBUS_BLOCK_DATA case. That needs to read
+				 * another byte with STOP bit set when the block data
+				 * response length is invalid to complete the transaction.
+				 */
+				if ((tmp & DW_IC_DATA_CMD_DAT) > I2C_SMBUS_BLOCK_MAX || tmp == 0)
+					tmp = 1;
+
 				len = i2c_dw_recv_len(dev, tmp);
 			}
 			*buf++ = tmp;
-- 
2.25.1


             reply	other threads:[~2023-05-23  8:25 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-23  8:21 Tam Nguyen [this message]
2023-05-24 12:33 ` [PATCH v1] i2c: designware: Handle invalid SMBus block data response length Jarkko Nikula
2023-05-25  9:30   ` Tam Chi Nguyen
2023-06-02  4:30     ` Tam Chi Nguyen
2023-06-05  7:41       ` Jarkko Nikula

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=20230523082118.10935-1-tamnguyenchi@os.amperecomputing.com \
    --to=tamnguyenchi@os.amperecomputing.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=chuong@os.amperecomputing.com \
    --cc=darren@os.amperecomputing.com \
    --cc=jarkko.nikula@linux.intel.com \
    --cc=jsd@semihalf.com \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    --cc=patches@amperecomputing.com \
    --cc=stable@vger.kernel.org \
    /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