public inbox for linux-tegra@vger.kernel.org
 help / color / mirror / Atom feed
From: Thierry Reding <thierry.reding@gmail.com>
To: Akhil R <akhilrajeev@nvidia.com>
Cc: christian.koenig@amd.com, digetx@gmail.com, jonathanh@nvidia.com,
	ldewangan@nvidia.com, linux-i2c@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org,
	sumit.semwal@linaro.org, wsa@kernel.org
Subject: Re: [PATCH v4 1/2] i2c: tegra: Fix PEC support for SMBUS block read
Date: Wed, 5 Apr 2023 14:25:06 +0200	[thread overview]
Message-ID: <ZC1oovV5CSfzvhd_@orome> (raw)
In-Reply-To: <20230324115924.64218-2-akhilrajeev@nvidia.com>

[-- Attachment #1: Type: text/plain, Size: 4557 bytes --]

On Fri, Mar 24, 2023 at 05:29:23PM +0530, Akhil R wrote:
> Update the msg->len value correctly for SMBUS block read. The discrepancy
> went unnoticed as msg->len is used in SMBUS transfers only when a PEC
> byte is added.
> 
> Fixes: d7583c8a5748 ("i2c: tegra: Add SMBus block read function")
> Signed-off-by: Akhil R <akhilrajeev@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 38 +++++++++++++++++++++++-----------
>  1 file changed, 26 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index 6aab84c8d22b..83e74b8baf67 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -245,6 +245,7 @@ struct tegra_i2c_hw_feature {
>   * @msg_err: error code for completed message
>   * @msg_buf: pointer to current message data
>   * @msg_buf_remaining: size of unsent data in the message buffer
> + * @msg_len: length of message in current transfer
>   * @msg_read: indicates that the transfer is a read access
>   * @timings: i2c timings information like bus frequency
>   * @multimaster_mode: indicates that I2C controller is in multi-master mode
> @@ -279,6 +280,7 @@ struct tegra_i2c_dev {
>  	size_t msg_buf_remaining;
>  	int msg_err;
>  	u8 *msg_buf;
> +	__u16 msg_len;
>  
>  	struct completion dma_complete;
>  	struct dma_chan *tx_dma_chan;
> @@ -1169,7 +1171,7 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
>  	else
>  		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
>  
> -	packet_header = msg->len - 1;
> +	packet_header = i2c_dev->msg_len - 1;
>  
>  	if (i2c_dev->dma_mode && !i2c_dev->msg_read)
>  		*dma_buf++ = packet_header;
> @@ -1242,20 +1244,32 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
>  		return err;
>  
>  	i2c_dev->msg_buf = msg->buf;
> +	i2c_dev->msg_len = msg->len;
>  
> -	/* The condition true implies smbus block read and len is already read */
> -	if (msg->flags & I2C_M_RECV_LEN && end_state != MSG_END_CONTINUE)
> -		i2c_dev->msg_buf = msg->buf + 1;
> -
> -	i2c_dev->msg_buf_remaining = msg->len;
>  	i2c_dev->msg_err = I2C_ERR_NONE;
>  	i2c_dev->msg_read = !!(msg->flags & I2C_M_RD);
>  	reinit_completion(&i2c_dev->msg_complete);
>  
> +	/* *
> +	 * For SMBUS block read command, read only 1 byte in the first transfer.
> +	 * Adjust that 1 byte for the next transfer in the msg buffer and msg
> +	 * length.
> +	 */
> +	if (msg->flags & I2C_M_RECV_LEN) {
> +		if (end_state == MSG_END_CONTINUE) {
> +			i2c_dev->msg_len = 1;
> +		} else {
> +			i2c_dev->msg_buf += 1;
> +			i2c_dev->msg_len -= 1;
> +		}
> +	}
> +
> +	i2c_dev->msg_buf_remaining = i2c_dev->msg_len;
> +
>  	if (i2c_dev->msg_read)
> -		xfer_size = msg->len;
> +		xfer_size = i2c_dev->msg_len;
>  	else
> -		xfer_size = msg->len + I2C_PACKET_HEADER_SIZE;
> +		xfer_size = i2c_dev->msg_len + I2C_PACKET_HEADER_SIZE;
>  
>  	xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
>  
> @@ -1295,7 +1309,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
>  	if (!i2c_dev->msg_read) {
>  		if (i2c_dev->dma_mode) {
>  			memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
> -			       msg->buf, msg->len);
> +			       msg->buf, i2c_dev->msg_len);
>  
>  			dma_sync_single_for_device(i2c_dev->dma_dev,
>  						   i2c_dev->dma_phys,
> @@ -1352,7 +1366,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
>  						i2c_dev->dma_phys,
>  						xfer_size, DMA_FROM_DEVICE);
>  
> -			memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, msg->len);
> +			memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);
>  		}
>  	}
>  
> @@ -1408,8 +1422,8 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
>  			ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
>  			if (ret)
>  				break;
> -			/* Set the read byte as msg len */
> -			msgs[i].len = msgs[i].buf[0];
> +			/* Set the msg length from first byte */
> +			msgs[i].len += msgs[i].buf[0];

I'm having trouble understanding why this change is needed. msg->len is
never changed in tegra_i2c_xfer_msg(), as far as I can tell, so it would
contain whatever was in it for the previous transfer. But since we want
to read the message length from the first byte, wouldn't the assignment
(i.e. the old code) be the right way to do that? If we add the length
from the first byte, we could potentially be reading more than whan the
first byte indicated.

What am I missing?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2023-04-05 12:25 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-24 11:59 [PATCH v4 0/2] Tegra I2C DMA and SMBus blockread updates Akhil R
2023-03-24 11:59 ` [PATCH v4 1/2] i2c: tegra: Fix PEC support for SMBUS block read Akhil R
2023-04-05 12:25   ` Thierry Reding [this message]
2023-04-05 16:11     ` Akhil R
2023-04-13  8:27       ` Thierry Reding
2023-04-13  9:40   ` Dmitry Osipenko
2023-03-24 11:59 ` [PATCH v4 2/2] i2c: tegra: Share same DMA channel for RX and TX Akhil R
2023-04-05 12:26   ` Thierry Reding

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=ZC1oovV5CSfzvhd_@orome \
    --to=thierry.reding@gmail.com \
    --cc=akhilrajeev@nvidia.com \
    --cc=christian.koenig@amd.com \
    --cc=digetx@gmail.com \
    --cc=jonathanh@nvidia.com \
    --cc=ldewangan@nvidia.com \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=sumit.semwal@linaro.org \
    --cc=wsa@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