i2c: i801: Fix block process call transactions
authorJean Delvare <jdelvare@suse.de>
Wed, 14 Feb 2024 14:59:39 +0000 (15:59 +0100)
committerAndi Shyti <andi.shyti@kernel.org>
Wed, 14 Feb 2024 21:15:38 +0000 (22:15 +0100)
According to the Intel datasheets, software must reset the block
buffer index twice for block process call transactions: once before
writing the outgoing data to the buffer, and once again before
reading the incoming data from the buffer.

The driver is currently missing the second reset, causing the wrong
portion of the block buffer to be read.

Signed-off-by: Jean Delvare <jdelvare@suse.de>
Reported-by: Piotr Zakowski <piotr.zakowski@intel.com>
Closes: https://lore.kernel.org/linux-i2c/20240213120553.7b0ab120@endymion.delvare/
Fixes: 315cd67c9453 ("i2c: i801: Add Block Write-Block Read Process Call support")
Reviewed-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
drivers/i2c/busses/i2c-i801.c

index 3932e8d96a17173fa3b4f7ad90ebcbb786e99370..2c36b36d7d516c851c8e9e44c8f90ce11fac0f13 100644 (file)
@@ -498,11 +498,10 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
        /* Set block buffer mode */
        outb_p(inb_p(SMBAUXCTL(priv)) | SMBAUXCTL_E32B, SMBAUXCTL(priv));
 
-       inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
-
        if (read_write == I2C_SMBUS_WRITE) {
                len = data->block[0];
                outb_p(len, SMBHSTDAT0(priv));
+               inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
                for (i = 0; i < len; i++)
                        outb_p(data->block[i+1], SMBBLKDAT(priv));
        }
@@ -520,6 +519,7 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
                }
 
                data->block[0] = len;
+               inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
                for (i = 0; i < len; i++)
                        data->block[i + 1] = inb_p(SMBBLKDAT(priv));
        }