Commit 97140342 authored by David Brownell's avatar David Brownell Committed by Jean Delvare
Browse files

i2c: Bus drivers return -Errno not -1



Tighten error paths used by various i2c adapters (mostly x86) so
they return real fault/errno codes instead of a "-1" (which is
most often interpreted as "-EPERM").  Build tested, with eyeball
review.

One minor initial goal is to have adapters consistently return
the code "-ENXIO" when addressing a device doesn't get an ACK
response, at least in the probe paths where they are already
good at stifling related logspam.

Signed-off-by: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent 6ea438ec
......@@ -320,7 +320,7 @@ static int try_address(struct i2c_adapter *i2c_adap,
unsigned char addr, int retries)
{
struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
int i, ret = -1;
int i, ret = 0;
for (i = 0; i <= retries; i++) {
ret = i2c_outb(i2c_adap, addr);
......@@ -508,7 +508,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
addr ^= 1;
ret = try_address(i2c_adap, addr, retries);
if ((ret != 1) && !nak_ok)
return -EREMOTEIO;
return -ENXIO;
}
return 0;
......
......@@ -259,7 +259,7 @@ static int ali1535_transaction(struct i2c_adapter *adap)
dev_err(&adap->dev,
"SMBus reset failed! (0x%02x) - controller or "
"device on bus is probably hung\n", temp);
return -1;
return -EBUSY;
}
} else {
/* check and clear done bit */
......@@ -281,12 +281,12 @@ static int ali1535_transaction(struct i2c_adapter *adap)
/* If the SMBus is still busy, we give up */
if (timeout >= MAX_TIMEOUT) {
result = -1;
result = -ETIMEDOUT;
dev_err(&adap->dev, "SMBus Timeout!\n");
}
if (temp & ALI1535_STS_FAIL) {
result = -1;
result = -EIO;
dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
}
......@@ -295,7 +295,7 @@ static int ali1535_transaction(struct i2c_adapter *adap)
* do a printk. This means that bus collisions go unreported.
*/
if (temp & ALI1535_STS_BUSERR) {
result = -1;
result = -ENXIO;
dev_dbg(&adap->dev,
"Error: no response or bus collision ADD=%02x\n",
inb_p(SMBHSTADD));
......@@ -303,13 +303,13 @@ static int ali1535_transaction(struct i2c_adapter *adap)
/* haven't ever seen this */
if (temp & ALI1535_STS_DEV) {
result = -1;
result = -EIO;
dev_err(&adap->dev, "Error: device error\n");
}
/* check to see if the "command complete" indication is set */
if (!(temp & ALI1535_STS_DONE)) {
result = -1;
result = -ETIMEDOUT;
dev_err(&adap->dev, "Error: command never completed\n");
}
......@@ -332,7 +332,7 @@ static int ali1535_transaction(struct i2c_adapter *adap)
return result;
}
/* Return -1 on error. */
/* Return negative errno on error. */
static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data *data)
......@@ -359,7 +359,7 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
switch (size) {
case I2C_SMBUS_PROC_CALL:
dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
result = -1;
result = -EOPNOTSUPP;
goto EXIT;
case I2C_SMBUS_QUICK:
outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
......@@ -420,11 +420,9 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
break;
}
if (ali1535_transaction(adap)) {
/* Error in transaction */
result = -1;
result = ali1535_transaction(adap);
if (result)
goto EXIT;
}
if ((read_write == I2C_SMBUS_WRITE) || (size == ALI1535_QUICK)) {
result = 0;
......
......@@ -67,6 +67,7 @@ static int ali1563_transaction(struct i2c_adapter * a, int size)
{
u32 data;
int timeout;
int status = -EIO;
dev_dbg(&a->dev, "Transaction (pre): STS=%02x, CNTL1=%02x, "
"CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
......@@ -103,13 +104,15 @@ static int ali1563_transaction(struct i2c_adapter * a, int size)
/* Issue 'kill' to host controller */
outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2);
data = inb_p(SMB_HST_STS);
status = -ETIMEDOUT;
}
/* device error - no response, ignore the autodetection case */
if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) {
dev_err(&a->dev, "Device error!\n");
if (data & HST_STS_DEVERR) {
if (size != HST_CNTL2_QUICK)
dev_err(&a->dev, "Device error!\n");
status = -ENXIO;
}
/* bus collision */
if (data & HST_STS_BUSERR) {
dev_err(&a->dev, "Bus collision!\n");
......@@ -122,13 +125,14 @@ static int ali1563_transaction(struct i2c_adapter * a, int size)
outb_p(0x0,SMB_HST_CNTL2);
}
return -1;
return status;
}
static int ali1563_block_start(struct i2c_adapter * a)
{
u32 data;
int timeout;
int status = -EIO;
dev_dbg(&a->dev, "Block (pre): STS=%02x, CNTL1=%02x, "
"CNTL2=%02x, CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
......@@ -164,13 +168,20 @@ static int ali1563_block_start(struct i2c_adapter * a)
if (timeout && !(data & HST_STS_BAD))
return 0;
if (timeout == 0)
status = -ETIMEDOUT;
if (data & HST_STS_DEVERR)
status = -ENXIO;
dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n",
timeout ? "Timeout " : "",
timeout ? "" : "Timeout ",
data & HST_STS_FAIL ? "Transaction Failed " : "",
data & HST_STS_BUSERR ? "No response or Bus Collision " : "",
data & HST_STS_DEVERR ? "Device Error " : "",
!(data & HST_STS_DONE) ? "Transaction Never Finished " : "");
return -1;
return status;
}
static int ali1563_block(struct i2c_adapter * a, union i2c_smbus_data * data, u8 rw)
......
......@@ -282,7 +282,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
dev_err(&adap->dev, "SMBus reset failed! (0x%02x) - "
"controller or device on bus is probably hung\n",
temp);
return -1;
return -EBUSY;
}
} else {
/* check and clear done bit */
......@@ -304,12 +304,12 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
/* If the SMBus is still busy, we give up */
if (timeout >= MAX_TIMEOUT) {
result = -1;
result = -ETIMEDOUT;
dev_err(&adap->dev, "SMBus Timeout!\n");
}
if (temp & ALI15X3_STS_TERM) {
result = -1;
result = -EIO;
dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
}
......@@ -320,7 +320,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
This means that bus collisions go unreported.
*/
if (temp & ALI15X3_STS_COLL) {
result = -1;
result = -ENXIO;
dev_dbg(&adap->dev,
"Error: no response or bus collision ADD=%02x\n",
inb_p(SMBHSTADD));
......@@ -328,7 +328,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
/* haven't ever seen this */
if (temp & ALI15X3_STS_DEV) {
result = -1;
result = -EIO;
dev_err(&adap->dev, "Error: device error\n");
}
dev_dbg(&adap->dev, "Transaction (post): STS=%02x, CNT=%02x, CMD=%02x, "
......@@ -338,7 +338,7 @@ static int ali15x3_transaction(struct i2c_adapter *adap)
return result;
}
/* Return -1 on error. */
/* Return negative errno on error. */
static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data * data)
......@@ -364,7 +364,7 @@ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
switch (size) {
case I2C_SMBUS_PROC_CALL:
dev_err(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
return -1;
return -EOPNOTSUPP;
case I2C_SMBUS_QUICK:
outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
SMBHSTADD);
......@@ -421,8 +421,9 @@ static s32 ali15x3_access(struct i2c_adapter * adap, u16 addr,
outb_p(size, SMBHSTCNT); /* output command */
if (ali15x3_transaction(adap)) /* Error in transaction */
return -1;
temp = ali15x3_transaction(adap);
if (temp)
return temp;
if ((read_write == I2C_SMBUS_WRITE) || (size == ALI15X3_QUICK))
return 0;
......
......@@ -58,7 +58,7 @@ static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr,
/* We exclude the multiplexed addresses */
if (addr == 0x4c || (addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30
|| addr == 0x18)
return -1;
return -ENXIO;
mutex_lock(&amd756_lock);
......@@ -86,7 +86,7 @@ static inline s32 amd756_access_channel(struct i2c_adapter * adap, u16 addr,
/* We exclude the non-multiplexed addresses */
if (addr != 0x4c && (addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30)
return -1;
return -ENXIO;
mutex_lock(&amd756_lock);
......
......@@ -151,17 +151,17 @@ static int amd756_transaction(struct i2c_adapter *adap)
}
if (temp & GS_PRERR_STS) {
result = -1;
result = -ENXIO;
dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n");
}
if (temp & GS_COL_STS) {
result = -1;
result = -EIO;
dev_warn(&adap->dev, "SMBus collision!\n");
}
if (temp & GS_TO_STS) {
result = -1;
result = -ETIMEDOUT;
dev_dbg(&adap->dev, "SMBus protocol timeout!\n");
}
......@@ -189,22 +189,23 @@ static int amd756_transaction(struct i2c_adapter *adap)
outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE);
msleep(100);
outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS);
return -1;
return -EIO;
}
/* Return -1 on error. */
/* Return negative errno on error. */
static s32 amd756_access(struct i2c_adapter * adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data * data)
{
int i, len;
int status;
/** TODO: Should I supporte the 10-bit transfers? */
switch (size) {
case I2C_SMBUS_PROC_CALL:
dev_dbg(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n");
/* TODO: Well... It is supported, I'm just not sure what to do here... */
return -1;
return -EOPNOTSUPP;
case I2C_SMBUS_QUICK:
outw_p(((addr & 0x7f) << 1) | (read_write & 0x01),
SMB_HOST_ADDRESS);
......@@ -256,8 +257,9 @@ static s32 amd756_access(struct i2c_adapter * adap, u16 addr,
/* How about enabling interrupts... */
outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE);
if (amd756_transaction(adap)) /* Error in transaction */
return -1;
status = amd756_transaction(adap);
if (status)
return status;
if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK))
return 0;
......
......@@ -77,7 +77,7 @@ static unsigned int amd_ec_wait_write(struct amd_smbus *smbus)
if (!timeout) {
dev_warn(&smbus->dev->dev,
"Timeout while waiting for IBF to clear\n");
return -1;
return -ETIMEDOUT;
}
return 0;
......@@ -93,7 +93,7 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
if (!timeout) {
dev_warn(&smbus->dev->dev,
"Timeout while waiting for OBF to set\n");
return -1;
return -ETIMEDOUT;
}
return 0;
......@@ -102,16 +102,21 @@ static unsigned int amd_ec_wait_read(struct amd_smbus *smbus)
static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
unsigned char *data)
{
if (amd_ec_wait_write(smbus))
return -1;
int status;
status = amd_ec_wait_write(smbus);
if (status)
return status;
outb(AMD_EC_CMD_RD, smbus->base + AMD_EC_CMD);
if (amd_ec_wait_write(smbus))
return -1;
status = amd_ec_wait_write(smbus);
if (status)
return status;
outb(address, smbus->base + AMD_EC_DATA);
if (amd_ec_wait_read(smbus))
return -1;
status = amd_ec_wait_read(smbus);
if (status)
return status;
*data = inb(smbus->base + AMD_EC_DATA);
return 0;
......@@ -120,16 +125,21 @@ static unsigned int amd_ec_read(struct amd_smbus *smbus, unsigned char address,
static unsigned int amd_ec_write(struct amd_smbus *smbus, unsigned char address,
unsigned char data)
{
if (amd_ec_wait_write(smbus))
return -1;
int status;
status = amd_ec_wait_write(smbus);
if (status)
return status;
outb(AMD_EC_CMD_WR, smbus->base + AMD_EC_CMD);
if (amd_ec_wait_write(smbus))
return -1;
status = amd_ec_wait_write(smbus);
if (status)
return status;
outb(address, smbus->base + AMD_EC_DATA);
if (amd_ec_wait_write(smbus))
return -1;
status = amd_ec_wait_write(smbus);
if (status)
return status;
outb(data, smbus->base + AMD_EC_DATA);
return 0;
......@@ -267,12 +277,17 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
default:
dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
return -1;
return -EOPNOTSUPP;
}
amd_ec_write(smbus, AMD_SMB_ADDR, addr << 1);
amd_ec_write(smbus, AMD_SMB_PRTCL, protocol);
/* FIXME this discards status from ec_read(); so temp[0] will
* hold stack garbage ... the rest of this routine will act
* nonsensically. Ignored ec_write() status might explain
* some such failures...
*/
amd_ec_read(smbus, AMD_SMB_STS, temp + 0);
if (~temp[0] & AMD_SMB_STS_DONE) {
......@@ -286,7 +301,7 @@ static s32 amd8111_access(struct i2c_adapter * adap, u16 addr,
}
if ((~temp[0] & AMD_SMB_STS_DONE) || (temp[0] & AMD_SMB_STS_STATUS))
return -1;
return -EIO;
if (read_write == I2C_SMBUS_WRITE)
return 0;
......
......@@ -151,7 +151,7 @@ static int i801_transaction(int xact)
outb_p(temp, SMBHSTSTS);
if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp);
return -1;
return -EBUSY;
} else {
dev_dbg(&I801_dev->dev, "Successful!\n");
}
......@@ -170,7 +170,7 @@ static int i801_transaction(int xact)
/* If the SMBus is still busy, we give up */
if (timeout >= MAX_TIMEOUT) {
dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
result = -1;
result = -ETIMEDOUT;
/* try to stop the current command */
dev_dbg(&I801_dev->dev, "Terminating the current operation\n");
outb_p(inb_p(SMBHSTCNT) | SMBHSTCNT_KILL, SMBHSTCNT);
......@@ -179,19 +179,19 @@ static int i801_transaction(int xact)
}
if (temp & SMBHSTSTS_FAILED) {
result = -1;
result = -EIO;
dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
}
if (temp & SMBHSTSTS_BUS_ERR) {
result = -1;
result = -EIO;
dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
"until next hard reset. (sorry!)\n");
/* Clock stops and slave is stuck in mid-transmission */
}
if (temp & SMBHSTSTS_DEV_ERR) {
result = -1;
result = -ENXIO;
dev_dbg(&I801_dev->dev, "Error: no response!\n");
}
......@@ -231,6 +231,7 @@ static int i801_block_transaction_by_block(union i2c_smbus_data *data,
char read_write, int hwpec)
{
int i, len;
int status;
inb_p(SMBHSTCNT); /* reset the data buffer index */
......@@ -242,14 +243,15 @@ static int i801_block_transaction_by_block(union i2c_smbus_data *data,
outb_p(data->block[i+1], SMBBLKDAT);
}
if (i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
I801_PEC_EN * hwpec))
return -1;
status = i801_transaction(I801_BLOCK_DATA | ENABLE_INT9 |
I801_PEC_EN * hwpec);
if (status)
return status;
if (read_write == I2C_SMBUS_READ) {
len = inb_p(SMBHSTDAT0);
if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
return -1;
return -EPROTO;
data->block[0] = len;
for (i = 0; i < len; i++)
......@@ -314,11 +316,11 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
dev_err(&I801_dev->dev,
"Reset failed! (%02x)\n", temp);
return -1;
return -EBUSY;
}
if (i != 1)
/* if die in middle of block transaction, fail */
return -1;
return -EIO;
}
if (i == 1)
......@@ -342,19 +344,19 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
msleep(1);
outb_p(inb_p(SMBHSTCNT) & (~SMBHSTCNT_KILL),
SMBHSTCNT);
result = -1;
result = -ETIMEDOUT;
dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
}
if (temp & SMBHSTSTS_FAILED) {
result = -1;
result = -EIO;
dev_dbg(&I801_dev->dev,
"Error: Failed bus transaction\n");
} else if (temp & SMBHSTSTS_BUS_ERR) {
result = -1;
result = -EIO;
dev_err(&I801_dev->dev, "Bus collision!\n");
} else if (temp & SMBHSTSTS_DEV_ERR) {
result = -1;
result = -ENXIO;
dev_dbg(&I801_dev->dev, "Error: no response!\n");
}
......@@ -362,7 +364,7 @@ static int i801_block_transaction_byte_by_byte(union i2c_smbus_data *data,
&& command != I2C_SMBUS_I2C_BLOCK_DATA) {
len = inb_p(SMBHSTDAT0);
if (len < 1 || len > I2C_SMBUS_BLOCK_MAX)
return -1;
return -EPROTO;
data->block[0] = len;
}
......@@ -394,7 +396,7 @@ static int i801_set_block_buffer_mode(void)
{
outb_p(inb_p(SMBAUXCTL) | SMBAUXCTL_E32B, SMBAUXCTL);
if ((inb_p(SMBAUXCTL) & SMBAUXCTL_E32B) == 0)
return -1;
return -EIO;
return 0;
}
......@@ -414,7 +416,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
} else if (!(i801_features & FEATURE_I2C_BLOCK_READ)) {
dev_err(&I801_dev->dev,
"I2C block read is unsupported!\n");
return -1;
return -EOPNOTSUPP;
}
}
......@@ -449,7 +451,7 @@ static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
return result;
}
/* Return -1 on error. */
/* Return negative errno on error. */
static s32 i801_access(struct i2c_adapter * adap, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data * data)
......@@ -514,7 +516,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
case I2C_SMBUS_PROC_CALL:
default:
dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
return -1;
return -EOPNOTSUPP;
}
if (hwpec) /* enable/disable hardware PEC */
......@@ -537,7 +539,7 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
if(block)
return ret;
if(ret)
return -1;
return ret;
if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
return 0;
......
......@@ -172,16 +172,16 @@ static int nforce2_check_status(struct i2c_adapter *adap)
dev_dbg(&adap->dev, "SMBus Timeout!\n");
if (smbus->can_abort)
nforce2_abort(adap);
return -1;
return -ETIMEDOUT;
}
if (!(temp & NVIDIA_SMB_STS_DONE) || (temp & NVIDIA_SMB_STS_STATUS)) {
dev_dbg(&adap->dev, "Transaction failed (0x%02x)!\n", temp);
return -1;
return -EIO;
}
return 0;
}
/* Return -1 on error */
/* Return negative errno on error */
static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
unsigned short flags, char read_write,
u8 command, int size, union i2c_smbus_data * data)
......@@ -189,7 +189,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
struct nforce2_smbus *smbus = adap->algo_data;
unsigned char protocol, pec;
u8 len;
int i;
int i, status;
protocol = (read_write == I2C_SMBUS_READ) ? NVIDIA_SMB_PRTCL_READ :
NVIDIA_SMB_PRTCL_WRITE;
......@@ -233,7 +233,7 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
"Transaction failed "
"(requested block size: %d)\n",
len);
return -1;
return -EINVAL;
}
outb_p(len, NVIDIA_SMB_BCNT);
for (i = 0; i < I2C_SMBUS_BLOCK_MAX; i++)
......@@ -245,14 +245,15 @@ static s32 nforce2_access(struct i2c_adapter * adap, u16 addr,
default:
dev_err(&adap->dev, "Unsupported transaction %d\n", size);
return -1;
return -EOPNOTSUPP;
}
outb_p((addr & 0x7f) << 1, NVIDIA_SMB_ADDR);
outb_p(protocol, NVIDIA_SMB_PRTCL);
if (nforce2_check_status(adap))
return -1;
status = nforce2_check_status(adap);