Re: [PATCH] i2c: i801: Fix block process call transactions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Jean,

thanks for looking into this!

On Wed, 2024-02-14 at 15:59 +0100, Jean Delvare wrote:
> 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@xxxxxxx>
> Reported-by: Piotr Zakowski <piotr.zakowski@xxxxxxxxx>
> Closes: https://lore.kernel.org/linux-i2c/20240213120553.7b0ab120@endymion.delvare/
> Fixes: 315cd67c9453 ("i2c: i801: Add Block Write-Block Read Process Call support")

According to all the datasheets I've been able to find, the patch
makes sense to me.

Reviewed-by: Alexander Sverdlin <alexander.sverdlin@xxxxxxxxx>

> ---
> Piotr, does this change make your tests succeed?
> 
> Alexander, I don't suppose you still have access to the hardware on
> which you were using block process call transactions back in 2019, but
> maybe you remember having to do the same change to make it work?

Nope, I cannot explain how this went unnoticed... I don't think
we had a downstream patch on top back than.

>  drivers/i2c/busses/i2c-i801.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> --- linux-6.6.orig/drivers/i2c/busses/i2c-i801.c
> +++ linux-6.6/drivers/i2c/busses/i2c-i801.c
> @@ -500,11 +500,10 @@ static int i801_block_transaction_by_blo
>  	/* 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));
>  	}
> @@ -522,6 +521,7 @@ static int i801_block_transaction_by_blo
>  		}
>  
>  		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));
>  	}
> 

-- 
Alexander Sverdlin.






[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux