linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
To: Corey Minyard <minyard@acm.org>
Cc: Jean Delvare <jdelvare@suse.com>,
	linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org,
	Corey Minyard <cminyard@mvista.com>
Subject: Re: [v2,05/10] i2c-i801: Consolidate calls to i801_check_post
Date: Thu, 9 Jun 2016 12:03:29 +0200	[thread overview]
Message-ID: <20160609100329.GG24234@mail.corp.redhat.com> (raw)
In-Reply-To: <1464570544-975-6-git-send-email-minyard@acm.org>

On May 29 2016 or thereabouts, Corey Minyard wrote:
> From: Corey Minyard <cminyard@mvista.com>
> 
> This was almost always called at the end of the transaction.  The
> only time it wasn't called was when a protocol violation occurred,
> and the error reporting was inconsistent there.
> 
> So have the transaction functions return positive status or a
> negative error if they detect an issue.  If a protocol violation
> does occur, always do a kill operation on the bus instead of just
> trying to finish the operation.  If there was a hardware issue,
> the code that was there to terminate the transaction could loop
> forever, and the kill seems more appropriate if something goes
> grossly wrong.
> 
> Signed-off-by: Corey Minyard <cminyard@mvista.com>
> ---

I *think* the patch is OK. I have a few comments.

>  drivers/i2c/busses/i2c-i801.c | 51 +++++++++++++++++++++----------------------
>  1 file changed, 25 insertions(+), 26 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
> index 8794e70..56db310 100644
> --- a/drivers/i2c/busses/i2c-i801.c
> +++ b/drivers/i2c/busses/i2c-i801.c
> @@ -317,7 +317,13 @@ static int i801_check_post(struct i801_priv *priv, int status)
>  	 * DEV_ERR.
>  	 */
>  	if (unlikely(status < 0)) {
> -		dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
> +		result = status;
> +		if (status == -EPROTO)
> +			dev_err(&priv->pci_dev->dev,
> +				"Illegal SMBus block read size %d\n",
> +				priv->len);

Not sure this is a good idea to map -EPROTO to "Illegal SMBus block read
size". True, it looks like it can only happens this way, but I would
rather see it mapped to "Protocol Error". Given that Protocol Error is
not very interesting in itself, I'd rather keep the error messages in
the callers only (except for ETIMEOUT where you can output an error
message).

> +		else
> +			dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
>  		/* try to stop the current command */
>  		dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
>  		outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL,
> @@ -333,7 +339,7 @@ static int i801_check_post(struct i801_priv *priv, int status)
>  			dev_err(&priv->pci_dev->dev,
>  				"Failed terminating the transaction\n");
>  		outb_p(STATUS_FLAGS, SMBHSTSTS(priv));
> -		return -ETIMEDOUT;
> +		return result;
>  	}
>  
>  	if (status & SMBHSTSTS_FAILED) {
> @@ -414,15 +420,14 @@ static int i801_transaction(struct i801_priv *priv, int xact)
>  				 "Timeout waiting for interrupt!\n");

Here, the code already dev_warn the timeout and later i801_check_post
will dev_err the timeout too. That's one too much IMO :)

>  		}
>  		priv->status = 0;
> -		return i801_check_post(priv, status);
> +		return status;
>  	}
>  
>  	/* the current contents of SMBHSTCNT can be overwritten, since PEC,
>  	 * SMBSCMD are passed in xact */
>  	outb_p(xact | SMBHSTCNT_START, SMBHSTCNT(priv));
>  
> -	status = i801_wait_intr(priv);
> -	return i801_check_post(priv, status);
> +	return i801_wait_intr(priv);
>  }
>  
>  static int i801_block_transaction_by_block(struct i801_priv *priv,
> @@ -444,11 +449,11 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
>  
>  	status = i801_transaction(priv, I801_BLOCK_DATA |
>  				  (hwpec ? SMBHSTCNT_PEC_EN : 0));
> -	if (status)
> +	if (status < 0 || status & STATUS_ERROR_FLAGS)
>  		return status;
>  
>  	if (read_write == I2C_SMBUS_READ) {
> -		len = inb_p(SMBHSTDAT0(priv));
> +		len = priv->len = inb_p(SMBHSTDAT0(priv));
>  		if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
>  			return -EPROTO;
>  
> @@ -456,7 +461,7 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
>  		for (i = 0; i < len; i++)
>  			data->block[i + 1] = inb_p(SMBBLKDAT(priv));
>  	}
> -	return 0;
> +	return status;
>  }
>  
>  static void i801_isr_byte_done(struct i801_priv *priv)
> @@ -590,7 +595,7 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
>  				 "Timeout waiting for interrupt!\n");
>  		}
>  		priv->status = 0;
> -		return i801_check_post(priv, status);
> +		return status;
>  	}
>  
>  	for (i = 1; i <= len; i++) {
> @@ -604,24 +609,14 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
>  
>  		status = i801_wait_byte_done(priv);
>  		if (status)
> -			goto exit;
> +			return status;
>  
>  		if (i == 1 && read_write == I2C_SMBUS_READ
>  		 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
> -			len = inb_p(SMBHSTDAT0(priv));
> -			if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
> -				dev_err(&priv->pci_dev->dev,
> -					"Illegal SMBus block read size %d\n",
> -					len);
> -				/* Recover */
> -				while (inb_p(SMBHSTSTS(priv)) &
> -				       SMBHSTSTS_HOST_BUSY)
> -					outb_p(SMBHSTSTS_BYTE_DONE,
> -					       SMBHSTSTS(priv));
> -				outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv));
> +			priv->len = inb_p(SMBHSTDAT0(priv));
> +			if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX)
>  				return -EPROTO;
> -			}
> -			data->block[0] = len;
> +			data->block[0] = len = priv->len;

Not entirely sure why the priv->len changes are interleaved in this
patch. I might be missing something, but it looks like it should not be
there or in a separate patch.

Cheers,
Benjamin

>  		}
>  
>  		/* Retrieve/store value in SMBBLKDAT */
> @@ -634,9 +629,7 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
>  		outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv));
>  	}
>  
> -	status = i801_wait_intr(priv);
> -exit:
> -	return i801_check_post(priv, status);
> +	return i801_wait_intr(priv);
>  }
>  
>  static int i801_set_block_buffer_mode(struct i801_priv *priv)
> @@ -791,6 +784,12 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
>  	else
>  		ret = i801_transaction(priv, xact);
>  
> +	/*
> +	 * ret can be status if positive or an error if negative.  Let
> +	 * the post check handle it.
> +	 */
> +	ret = i801_check_post(priv, ret);
> +
>  	if (hostc >= 0)
>  		pci_write_config_byte(priv->pci_dev, SMBHSTCFG, hostc);
>  

  reply	other threads:[~2016-06-09 10:03 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-30  1:08 [PATCH v2 00/10] i2c-i801: Various cleanups minyard
2016-05-30  1:08 ` [PATCH v2 01/10] i2c-i801: Remove hwpec from block byte-by-byte function minyard
2016-06-09  9:36   ` [v2,01/10] " Benjamin Tissoires
2016-05-30  1:08 ` [PATCH v2 02/10] i2c-i801: Move hostcfg set/reset to i801_access() minyard
2016-06-09  9:39   ` [v2,02/10] " Benjamin Tissoires
2016-06-10 10:43     ` Corey Minyard
2016-05-30  1:08 ` [PATCH v2 03/10] i2c-i801: Move hwpec handling into block transaction minyard
2016-06-09  9:42   ` [v2,03/10] " Benjamin Tissoires
2016-05-30  1:08 ` [PATCH v2 04/10] i2c-i801: Consolidate calls to i801_check_pre() minyard
2016-06-09  9:44   ` [v2,04/10] " Benjamin Tissoires
2016-06-10 10:52     ` Corey Minyard
2016-05-30  1:08 ` [PATCH v2 05/10] i2c-i801: Consolidate calls to i801_check_post minyard
2016-06-09 10:03   ` Benjamin Tissoires [this message]
2016-06-10 11:09     ` [v2,05/10] " Corey Minyard
2016-05-30  1:09 ` [PATCH v2 06/10] i2c-i801: Pass around a boolean read/write variable minyard
2016-06-09 10:05   ` [v2,06/10] " Benjamin Tissoires
2016-05-30  1:09 ` [PATCH v2 07/10] i2c-i801: Fix some inconsistent variable names minyard
2016-06-09 14:01   ` [v2,07/10] " Benjamin Tissoires
2016-06-10 11:12     ` Corey Minyard
2016-05-30  1:09 ` [PATCH v2 08/10] i2c-i801: Handle a protocol error in byte-by-byte isr minyard
2016-06-09 14:07   ` [v2,08/10] " Benjamin Tissoires
2016-05-30  1:09 ` [PATCH v2 09/10] i2c-i801: Null isr data buffer when done with it minyard
2016-06-09 14:14   ` [v2,09/10] " Benjamin Tissoires
2016-05-30  1:09 ` [PATCH v2 10/10] i2c-i801: Only write the host control reg when necessary minyard

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=20160609100329.GG24234@mail.corp.redhat.com \
    --to=benjamin.tissoires@redhat.com \
    --cc=cminyard@mvista.com \
    --cc=jdelvare@suse.com \
    --cc=linux-i2c@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=minyard@acm.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;
as well as URLs for NNTP newsgroup(s).