mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-12 00:00:00 +00:00
i2c-core: Return -Errno, not -1
More updates to the I2C stack's fault reporting: make the core stop returning "-1" (usually "-EPERM") for all faults. Instead, pass lower level fault code up the stack, or return some appropriate errno. This patch happens to touch almost exclusively SMBus calls. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Jean Delvare <khali@linux-fr.org>
This commit is contained in:
parent
75415490d6
commit
24a5bb7b18
@ -598,10 +598,10 @@ be added back later if needed:
|
|||||||
u8 command, u8 length,
|
u8 command, u8 length,
|
||||||
u8 *values)
|
u8 *values)
|
||||||
|
|
||||||
All these transactions return -1 on failure. The 'write' transactions
|
All these transactions return a negative errno value on failure. The 'write'
|
||||||
return 0 on success; the 'read' transactions return the read value, except
|
transactions return 0 on success; the 'read' transactions return the read
|
||||||
for read_block, which returns the number of values read. The block buffers
|
value, except for block transactions, which return the number of values
|
||||||
need not be longer than 32 bytes.
|
read. The block buffers need not be longer than 32 bytes.
|
||||||
|
|
||||||
You can read the file `smbus-protocol' for more information about the
|
You can read the file `smbus-protocol' for more information about the
|
||||||
actual SMBus protocol.
|
actual SMBus protocol.
|
||||||
|
@ -974,7 +974,7 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
|
|||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
dev_dbg(&adap->dev, "I2C level transfers not supported\n");
|
dev_dbg(&adap->dev, "I2C level transfers not supported\n");
|
||||||
return -ENOSYS;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(i2c_transfer);
|
EXPORT_SYMBOL(i2c_transfer);
|
||||||
@ -1106,7 +1106,7 @@ int i2c_probe(struct i2c_adapter *adapter,
|
|||||||
|
|
||||||
dev_warn(&adapter->dev, "SMBus Quick command not supported, "
|
dev_warn(&adapter->dev, "SMBus Quick command not supported, "
|
||||||
"can't probe for chips\n");
|
"can't probe for chips\n");
|
||||||
return -1;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Probe entries are done second, and are not affected by ignore
|
/* Probe entries are done second, and are not affected by ignore
|
||||||
@ -1298,7 +1298,7 @@ static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg)
|
|||||||
if (rpec != cpec) {
|
if (rpec != cpec) {
|
||||||
pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n",
|
pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n",
|
||||||
rpec, cpec);
|
rpec, cpec);
|
||||||
return -1;
|
return -EBADMSG;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1313,11 +1313,12 @@ EXPORT_SYMBOL(i2c_smbus_write_quick);
|
|||||||
s32 i2c_smbus_read_byte(struct i2c_client *client)
|
s32 i2c_smbus_read_byte(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
union i2c_smbus_data data;
|
union i2c_smbus_data data;
|
||||||
if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,
|
int status;
|
||||||
I2C_SMBUS_READ,0,I2C_SMBUS_BYTE, &data))
|
|
||||||
return -1;
|
status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
|
||||||
else
|
I2C_SMBUS_READ, 0,
|
||||||
return data.byte;
|
I2C_SMBUS_BYTE, &data);
|
||||||
|
return (status < 0) ? status : data.byte;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(i2c_smbus_read_byte);
|
EXPORT_SYMBOL(i2c_smbus_read_byte);
|
||||||
|
|
||||||
@ -1331,11 +1332,12 @@ EXPORT_SYMBOL(i2c_smbus_write_byte);
|
|||||||
s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command)
|
s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command)
|
||||||
{
|
{
|
||||||
union i2c_smbus_data data;
|
union i2c_smbus_data data;
|
||||||
if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,
|
int status;
|
||||||
I2C_SMBUS_READ,command, I2C_SMBUS_BYTE_DATA,&data))
|
|
||||||
return -1;
|
status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
|
||||||
else
|
I2C_SMBUS_READ, command,
|
||||||
return data.byte;
|
I2C_SMBUS_BYTE_DATA, &data);
|
||||||
|
return (status < 0) ? status : data.byte;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(i2c_smbus_read_byte_data);
|
EXPORT_SYMBOL(i2c_smbus_read_byte_data);
|
||||||
|
|
||||||
@ -1352,11 +1354,12 @@ EXPORT_SYMBOL(i2c_smbus_write_byte_data);
|
|||||||
s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command)
|
s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command)
|
||||||
{
|
{
|
||||||
union i2c_smbus_data data;
|
union i2c_smbus_data data;
|
||||||
if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,
|
int status;
|
||||||
I2C_SMBUS_READ,command, I2C_SMBUS_WORD_DATA, &data))
|
|
||||||
return -1;
|
status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
|
||||||
else
|
I2C_SMBUS_READ, command,
|
||||||
return data.word;
|
I2C_SMBUS_WORD_DATA, &data);
|
||||||
|
return (status < 0) ? status : data.word;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(i2c_smbus_read_word_data);
|
EXPORT_SYMBOL(i2c_smbus_read_word_data);
|
||||||
|
|
||||||
@ -1390,11 +1393,13 @@ s32 i2c_smbus_read_block_data(struct i2c_client *client, u8 command,
|
|||||||
u8 *values)
|
u8 *values)
|
||||||
{
|
{
|
||||||
union i2c_smbus_data data;
|
union i2c_smbus_data data;
|
||||||
|
int status;
|
||||||
|
|
||||||
if (i2c_smbus_xfer(client->adapter, client->addr, client->flags,
|
status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
|
||||||
I2C_SMBUS_READ, command,
|
I2C_SMBUS_READ, command,
|
||||||
I2C_SMBUS_BLOCK_DATA, &data))
|
I2C_SMBUS_BLOCK_DATA, &data);
|
||||||
return -1;
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
memcpy(values, &data.block[1], data.block[0]);
|
memcpy(values, &data.block[1], data.block[0]);
|
||||||
return data.block[0];
|
return data.block[0];
|
||||||
@ -1421,14 +1426,16 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command,
|
|||||||
u8 length, u8 *values)
|
u8 length, u8 *values)
|
||||||
{
|
{
|
||||||
union i2c_smbus_data data;
|
union i2c_smbus_data data;
|
||||||
|
int status;
|
||||||
|
|
||||||
if (length > I2C_SMBUS_BLOCK_MAX)
|
if (length > I2C_SMBUS_BLOCK_MAX)
|
||||||
length = I2C_SMBUS_BLOCK_MAX;
|
length = I2C_SMBUS_BLOCK_MAX;
|
||||||
data.block[0] = length;
|
data.block[0] = length;
|
||||||
if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,
|
status = i2c_smbus_xfer(client->adapter, client->addr, client->flags,
|
||||||
I2C_SMBUS_READ,command,
|
I2C_SMBUS_READ, command,
|
||||||
I2C_SMBUS_I2C_BLOCK_DATA,&data))
|
I2C_SMBUS_I2C_BLOCK_DATA, &data);
|
||||||
return -1;
|
if (status < 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
memcpy(values, &data.block[1], data.block[0]);
|
memcpy(values, &data.block[1], data.block[0]);
|
||||||
return data.block[0];
|
return data.block[0];
|
||||||
@ -1469,6 +1476,7 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
|
|||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
u8 partial_pec = 0;
|
u8 partial_pec = 0;
|
||||||
|
int status;
|
||||||
|
|
||||||
msgbuf0[0] = command;
|
msgbuf0[0] = command;
|
||||||
switch(size) {
|
switch(size) {
|
||||||
@ -1518,10 +1526,10 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
|
|||||||
} else {
|
} else {
|
||||||
msg[0].len = data->block[0] + 2;
|
msg[0].len = data->block[0] + 2;
|
||||||
if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {
|
if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 2) {
|
||||||
dev_err(&adapter->dev, "smbus_access called with "
|
dev_err(&adapter->dev,
|
||||||
"invalid block write size (%d)\n",
|
"Invalid block write size %d\n",
|
||||||
data->block[0]);
|
data->block[0]);
|
||||||
return -1;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
for (i = 1; i < msg[0].len; i++)
|
for (i = 1; i < msg[0].len; i++)
|
||||||
msgbuf0[i] = data->block[i-1];
|
msgbuf0[i] = data->block[i-1];
|
||||||
@ -1531,10 +1539,10 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
|
|||||||
num = 2; /* Another special case */
|
num = 2; /* Another special case */
|
||||||
read_write = I2C_SMBUS_READ;
|
read_write = I2C_SMBUS_READ;
|
||||||
if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
|
if (data->block[0] > I2C_SMBUS_BLOCK_MAX) {
|
||||||
dev_err(&adapter->dev, "%s called with invalid "
|
dev_err(&adapter->dev,
|
||||||
"block proc call size (%d)\n", __func__,
|
"Invalid block write size %d\n",
|
||||||
data->block[0]);
|
data->block[0]);
|
||||||
return -1;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
msg[0].len = data->block[0] + 2;
|
msg[0].len = data->block[0] + 2;
|
||||||
for (i = 1; i < msg[0].len; i++)
|
for (i = 1; i < msg[0].len; i++)
|
||||||
@ -1549,19 +1557,18 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
|
|||||||
} else {
|
} else {
|
||||||
msg[0].len = data->block[0] + 1;
|
msg[0].len = data->block[0] + 1;
|
||||||
if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {
|
if (msg[0].len > I2C_SMBUS_BLOCK_MAX + 1) {
|
||||||
dev_err(&adapter->dev, "i2c_smbus_xfer_emulated called with "
|
dev_err(&adapter->dev,
|
||||||
"invalid block write size (%d)\n",
|
"Invalid block write size %d\n",
|
||||||
data->block[0]);
|
data->block[0]);
|
||||||
return -1;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
for (i = 1; i <= data->block[0]; i++)
|
for (i = 1; i <= data->block[0]; i++)
|
||||||
msgbuf0[i] = data->block[i];
|
msgbuf0[i] = data->block[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(&adapter->dev, "smbus_access called with invalid size (%d)\n",
|
dev_err(&adapter->dev, "Unsupported transaction %d\n", size);
|
||||||
size);
|
return -EOPNOTSUPP;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK
|
i = ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK
|
||||||
@ -1579,13 +1586,15 @@ static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
|
|||||||
msg[num-1].len++;
|
msg[num-1].len++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i2c_transfer(adapter, msg, num) < 0)
|
status = i2c_transfer(adapter, msg, num);
|
||||||
return -1;
|
if (status < 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
/* Check PEC if last message is a read */
|
/* Check PEC if last message is a read */
|
||||||
if (i && (msg[num-1].flags & I2C_M_RD)) {
|
if (i && (msg[num-1].flags & I2C_M_RD)) {
|
||||||
if (i2c_smbus_check_pec(partial_pec, &msg[num-1]) < 0)
|
status = i2c_smbus_check_pec(partial_pec, &msg[num-1]);
|
||||||
return -1;
|
if (status < 0)
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read_write == I2C_SMBUS_READ)
|
if (read_write == I2C_SMBUS_READ)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user