Thread (2 messages) 2 messages, 1 author, 2025-08-20

[BUG] hid-mcp2221: I2C timeouts cause permanent bus lockup

From: Feliks Peysakhov <hidden>
Date: 2025-08-20 14:47:17
Also in: linux-i2c

Hi Rishi Gupta,

I'm experiencing an issue with the hid-mcp2221 driver where I2C operations
to non-existent addresses cause timeouts that permanently lock the I2C bus,
requiring a USB device reset to recover.

**Problem Description:**
When sending an I2C command to an empty/non-existent address, the operation
times out and all subsequent I2C operations fail until the MCP2221 USB device
is physically reset. This can also happen if sending a command to a valid address,
but there is a connection issue and the request is not returned.

**Expected Behavior:**
The driver should handle timeouts gracefully and reset the I2C bus state
automatically, similar to how the Microchip-provided driver handles this scenario.

**System Information:**
- Kernel version: 6.8.0-59-generic #61~22.04.1-Ubuntu
- Repo from Canonical: https://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/jammy/commit/drivers/hid/hid-mcp2221.c?h=Ubuntu-hwe-6.8-6.8.0-52.53_22.04.1
- Driver: hid-mcp2221
- Device: MCP2221A USB-to-I2C bridge (04d8:00dd)

**Steps to Reproduce:**
1. Send I2C command to non-existent address (e.g., 0x99)
2. Operation times out
3. All subsequent I2C operations fail with timeout errors, even to a valid address after that.
4. Only USB device reset restores functionality

**Comparison:**
The Microchip-provided i2c-mcp2221 driver (from their example code) handles
this scenario with some form of bus recovery. In fact I noticed that the LK driver
used to do the same until it was removed in this commit. This includes a full
reset of the I2C bus on the chip via a set speed command. I can see why this
was cleaned up since its not efficient.
https://github.com/torvalds/linux/commit/02a46753601a24e1673d9c28173121055e8e6cc9

**Impact:**
This makes the driver unreliable for production I2C applications where addressing
non-existent devices might occur during bus scanning or device detection routines.
For our use cases the greatest risk could be a board that is not powered up fully or a
mistake on the user side where nothing is connected forcing the chip to lock up
for any subsequent R/Ws.

**Proposed Solution:**
The driver should implement automatic I2C bus cancellation/reset when
operations timeout, similar to the recovery logic in the Microchip driver.
I think potentially there are some cancels missing in the mcp_i2c_write
and mcp_i2c_smbus_read functions.

I noticed there are cancels in place that are trying to be called but also failing
since the chip has a successful return status, but then sets a NACK flag. The
cancel commands themselves are failing at the chip. I noticed that cancels
do not work until the chip actually reports an error state.
--- a/hid-mcp2221.c
+++ b/hid-mcp2221.c
@@ -318,6 +318,8 @@ static int mcp_i2c_write(struct mcp2221 *mcp,
             ret = mcp_send_data_req_status(mcp, mcp->txbuf, len + 4);
             if (ret) {
+                      usleep_range(980, 1000);
+                      mcp_cancel_last_cmd(mcp);
                     return ret;
             }
@@ -399,6 +401,8 @@ static int mcp_i2c_smbus_read(struct mcp2221 *mcp,
     ret = mcp_send_data_req_status(mcp, mcp->txbuf, 4);
     if (ret) {
+              usleep_range(980, 1000);
+              mcp_cancel_last_cmd(mcp);
             return ret;
     }
I'm happy to provide more details, test patches, or assist with debugging.
Please let me know what you think.

Best regards,
Feliks Peysakhov

P.S. Sorry for the duplicate email resent to mailing list as plain text
This message is intended solely for the Addressee and may contain information that is PROPRIETARY and CONFIDENTIAL. If you are not the intended recipient and/or are not responsible for delivery of the message to such intended recipient, or if you believe you have received this communication in error, please do not print, copy, retransmit, disseminate, or otherwise use the information. Please notify the sender immediately that you have received this e-mail in error, and please delete all copies of the message and its attachments that you have received. Thank You. Persistent Systems, LLC, www.persistentsystems.com
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help