Commit 29dae457 authored by Heiner Kallweit's avatar Heiner Kallweit Committed by Andi Shyti

i2c: i801: Add SMBUS_LEN_SENTINEL

Add a sentinel length value that is used to check whether we should
read and use the length value provided by the slave device.
This simplifies the currently used checks.
Signed-off-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: default avatarAndi Shyti <andi.shyti@kernel.org>
Signed-off-by: default avatarAndi Shyti <andi.shyti@kernel.org>
parent 6ff9d46c
...@@ -205,6 +205,8 @@ ...@@ -205,6 +205,8 @@
#define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \ #define STATUS_FLAGS (SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR | \
STATUS_ERROR_FLAGS) STATUS_ERROR_FLAGS)
#define SMBUS_LEN_SENTINEL (I2C_SMBUS_BLOCK_MAX + 1)
/* Older devices have their ID defined in <linux/pci_ids.h> */ /* Older devices have their ID defined in <linux/pci_ids.h> */
#define PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS 0x02a3 #define PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS 0x02a3
#define PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS 0x06a3 #define PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS 0x06a3
...@@ -541,9 +543,12 @@ static int i801_block_transaction_by_block(struct i801_priv *priv, ...@@ -541,9 +543,12 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
static void i801_isr_byte_done(struct i801_priv *priv) static void i801_isr_byte_done(struct i801_priv *priv)
{ {
if (priv->is_read) { if (priv->is_read) {
/* For SMBus block reads, length is received with first byte */ /*
if (((priv->cmd & 0x1c) == I801_BLOCK_DATA) && * At transfer start i801_smbus_block_transaction() marks
(priv->count == 0)) { * the block length as invalid. Check for this sentinel value
* and read the block length from SMBHSTDAT0.
*/
if (priv->len == SMBUS_LEN_SENTINEL) {
priv->len = inb_p(SMBHSTDAT0(priv)); priv->len = inb_p(SMBHSTDAT0(priv));
if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX) { if (priv->len < 1 || priv->len > I2C_SMBUS_BLOCK_MAX) {
dev_err(&priv->pci_dev->dev, dev_err(&priv->pci_dev->dev,
...@@ -698,8 +703,12 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, ...@@ -698,8 +703,12 @@ static int i801_block_transaction_byte_by_byte(struct i801_priv *priv,
if (status) if (status)
return status; return status;
if (i == 1 && read_write == I2C_SMBUS_READ /*
&& command != I2C_SMBUS_I2C_BLOCK_DATA) { * At transfer start i801_smbus_block_transaction() marks
* the block length as invalid. Check for this sentinel value
* and read the block length from SMBHSTDAT0.
*/
if (len == SMBUS_LEN_SENTINEL) {
len = inb_p(SMBHSTDAT0(priv)); len = inb_p(SMBHSTDAT0(priv));
if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) { if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) {
dev_err(&priv->pci_dev->dev, dev_err(&priv->pci_dev->dev,
...@@ -806,7 +815,8 @@ static int i801_smbus_block_transaction(struct i801_priv *priv, union i2c_smbus_ ...@@ -806,7 +815,8 @@ static int i801_smbus_block_transaction(struct i801_priv *priv, union i2c_smbus_
u8 addr, u8 hstcmd, char read_write, int command) u8 addr, u8 hstcmd, char read_write, int command)
{ {
if (read_write == I2C_SMBUS_READ && command == I2C_SMBUS_BLOCK_DATA) if (read_write == I2C_SMBUS_READ && command == I2C_SMBUS_BLOCK_DATA)
data->block[0] = I2C_SMBUS_BLOCK_MAX; /* Mark block length as invalid */
data->block[0] = SMBUS_LEN_SENTINEL;
else if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) else if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX)
return -EPROTO; return -EPROTO;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment