drivers/i2c/busses/i2c-xiic.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
This series fixes three independent bugs in the Xilinx AXI IIC driver
that together make SMBus block reads with PEC return -EBADMSG or -EIO
on otherwise clean transfers. They only surface when the client has
I2C_CLIENT_PEC set; non-PEC block reads happen to mask each issue in
turn.
The problems were uncovered driving an adm1266 PMBus device behind a
Xilinx AXI IIC FPGA block and reading its 64-byte blackbox record.
Patch 1 stops xiic_smbus_block_read_setup() from truncating rx_msg->len.
The i2c core appends a byte to msg->len when PEC is enabled, so
overwriting the length to "block size + 1" silently drops the PEC byte
and i2c_smbus_check_pec() then reads the last payload byte as the PEC.
Patch 2 raises the RX_FULL threshold so the interrupt only fires once
every remaining byte (payload plus optional PEC) is already buffered in
the FIFO. The previous threshold of rxmsg_len - 2 caused the
bytes_rem == 1 path in xiic_read_rx() to NACK a byte still on the wire.
Patch 3 stops the BNB handler from forcing tx_msg->len = 1 to signal
completion. tx_msg and rx_msg alias the same i2c_msg during a receive,
so this also clobbered rx_msg->len; and because tx_pos is already at 2
in the PEC case, the unsigned subtraction in xiic_tx_space() underflowed
and the STATE_DONE check fell through to STATE_ERROR. Advancing tx_pos
up to msg->len drives tx_space to zero without touching the length.
All three patches are pure bug fixes; non-PEC behaviour is unchanged.
Tested on real hardware -- a Xilinx AXI IIC controller talking to an
adm1266, where 64-byte PEC-checked block reads now complete cleanly.
Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai>
---
Abdurrahman Hussain (3):
i2c: xiic: preserve PEC byte length in SMBus block read setup
i2c: xiic: defer RX_FULL until all trailing bytes are in FIFO
i2c: xiic: don't clobber msg->len to signal block-read completion
drivers/i2c/busses/i2c-xiic.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
---
base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
change-id: 20260427-i2c-xiic-2aeb501ec02a
Best regards,
--
Abdurrahman Hussain <abdurrahman@nexthop.ai>
On Tue, Apr 28, 2026 at 5:48 AM Abdurrahman Hussain via B4 Relay <devnull+abdurrahman.nexthop.ai@kernel.org> wrote: > > This series fixes three independent bugs in the Xilinx AXI IIC driver > that together make SMBus block reads with PEC return -EBADMSG or -EIO > on otherwise clean transfers. They only surface when the client has > I2C_CLIENT_PEC set; non-PEC block reads happen to mask each issue in > turn. > > The problems were uncovered driving an adm1266 PMBus device behind a > Xilinx AXI IIC FPGA block and reading its 64-byte blackbox record. > > Patch 1 stops xiic_smbus_block_read_setup() from truncating rx_msg->len. > The i2c core appends a byte to msg->len when PEC is enabled, so > overwriting the length to "block size + 1" silently drops the PEC byte > and i2c_smbus_check_pec() then reads the last payload byte as the PEC. > > Patch 2 raises the RX_FULL threshold so the interrupt only fires once > every remaining byte (payload plus optional PEC) is already buffered in > the FIFO. The previous threshold of rxmsg_len - 2 caused the > bytes_rem == 1 path in xiic_read_rx() to NACK a byte still on the wire. > > Patch 3 stops the BNB handler from forcing tx_msg->len = 1 to signal > completion. tx_msg and rx_msg alias the same i2c_msg during a receive, > so this also clobbered rx_msg->len; and because tx_pos is already at 2 > in the PEC case, the unsigned subtraction in xiic_tx_space() underflowed > and the STATE_DONE check fell through to STATE_ERROR. Advancing tx_pos > up to msg->len drives tx_space to zero without touching the length. > > All three patches are pure bug fixes; non-PEC behaviour is unchanged. > Tested on real hardware -- a Xilinx AXI IIC controller talking to an > adm1266, where 64-byte PEC-checked block reads now complete cleanly. > > Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai> LGTM Reviewed-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
On 6/9/26 16:26, Shubhrajyoti Datta wrote: > On Tue, Apr 28, 2026 at 5:48 AM Abdurrahman Hussain via B4 Relay > <devnull+abdurrahman.nexthop.ai@kernel.org> wrote: >> >> This series fixes three independent bugs in the Xilinx AXI IIC driver >> that together make SMBus block reads with PEC return -EBADMSG or -EIO >> on otherwise clean transfers. They only surface when the client has >> I2C_CLIENT_PEC set; non-PEC block reads happen to mask each issue in >> turn. >> >> The problems were uncovered driving an adm1266 PMBus device behind a >> Xilinx AXI IIC FPGA block and reading its 64-byte blackbox record. >> >> Patch 1 stops xiic_smbus_block_read_setup() from truncating rx_msg->len. >> The i2c core appends a byte to msg->len when PEC is enabled, so >> overwriting the length to "block size + 1" silently drops the PEC byte >> and i2c_smbus_check_pec() then reads the last payload byte as the PEC. >> >> Patch 2 raises the RX_FULL threshold so the interrupt only fires once >> every remaining byte (payload plus optional PEC) is already buffered in >> the FIFO. The previous threshold of rxmsg_len - 2 caused the >> bytes_rem == 1 path in xiic_read_rx() to NACK a byte still on the wire. >> >> Patch 3 stops the BNB handler from forcing tx_msg->len = 1 to signal >> completion. tx_msg and rx_msg alias the same i2c_msg during a receive, >> so this also clobbered rx_msg->len; and because tx_pos is already at 2 >> in the PEC case, the unsigned subtraction in xiic_tx_space() underflowed >> and the STATE_DONE check fell through to STATE_ERROR. Advancing tx_pos >> up to msg->len drives tx_space to zero without touching the length. >> >> All three patches are pure bug fixes; non-PEC behaviour is unchanged. >> Tested on real hardware -- a Xilinx AXI IIC controller talking to an >> adm1266, where 64-byte PEC-checked block reads now complete cleanly. >> >> Signed-off-by: Abdurrahman Hussain <abdurrahman@nexthop.ai> > > LGTM > Reviewed-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com> Acked-by: Michal Simek <michal.simek@amd.com> Thanks, Michal
© 2016 - 2026 Red Hat, Inc.